# Будівництво three lumcid-nmt: Production- ready (EasyNMT сумісне) Translation Service

## Вступ

Реалізація FastAPI EXACT копіює чудовий, але покинутий проект роботи з нейронним апаратом. https: // gitub.com/UKPLAB/EasyNMT).

Але я додав БАГАТЬОХ гарних рис, щоб збільшити надійність і підготувати її до використання у виробничій системі.[Думайте про те, що швидкий переклад сам підтримується...](https://github.com/scottgal/mostlylucid.activetranslatetag)).

З самого початку цього блогу, великим захопленням стали статті у автотрансляційних блогах.

ТАК Я знаю, що "Google робить це в браузерах і т.д., але справа не в цьому.`mostlylucid-nmt`Я хотіла знати, як це зробити!

Крім того, приємно вітати людей, які не читають англійською (навіть якщо вони читають англійську як другу мову, це важче опрацювати).[Тож я вирішив, як це зробити, і поділився тим, як побудувати таку систему.](#interactive-demo-page)О, і вона дала мені ідеї щодо того, як використовувати текст у ASP.NET для автоматичного локалізації тексту (включаючи динамічний текст) за допомогою SNR & хитрої системи оновлення реального часу. (

Залишайтеся на зв'язку![О, і я зробив демонстрацію доступною тут; https: // nmtdemo. methulicid.net/demo / вона працює лише у старому ноутбуку без GPU, але надає вам ідею (і дозволяє мені перевірити lengevity).](https://www.mostlylucid.net/blog/category/EasyNMT)По суті, люди пишуть нісенітниці текст, який є ДУЖЕ шумним для машин, щоб ефективно поводитися.

Отже, багато з них з'ясовували, як працювати з FasyNMT (це був справді дослідний проект).

[Зараз](https://github.com/scottgal/mostlylucid-nmt)

[![призначена для того, щоб бути випробуваною битвою (також перекладаючи десятки тисяч слів тут!) корисною системою для будь - якого перекладу.](https://img.shields.io/docker/pulls/scottgal/mostlylucid-nmt)](https://hub.docker.com/r/scottgal/mostlylucid-nmt)
[![Вавельський API.](https://img.shields.io/docker/v/scottgal/mostlylucid-nmt/cpu?label=cpu)](https://hub.docker.com/r/scottgal/mostlylucid-nmt)
[![У нього також є всі знання, які я маю від трьох десятиліть створення виробничих серверів та систем.](https://img.shields.io/docker/v/scottgal/mostlylucid-nmt/cpu-min?label=cpu-min)](https://hub.docker.com/r/scottgal/mostlylucid-nmt)
[![Перебіг з 429 кодів, щоб повідомити клієнтам про вихід, повернувши метадані про переклади, щоб допомогти клієнтам, додатковим кінцевим пунктам отримати більше даних і COURSE](https://img.shields.io/docker/v/scottgal/mostlylucid-nmt/gpu?label=gpu)](https://hub.docker.com/r/scottgal/mostlylucid-nmt)
[![сторінка демонстрації](https://img.shields.io/docker/v/scottgal/mostlylucid-nmt/gpu-min?label=gpu-min)](https://hub.docker.com/r/scottgal/mostlylucid-nmt)

## що дозволяє мені обом розвиватися так само добре, як тобі піти на гру.

[I](#interactive-demo-page)записано цілу систему`http://<server>:<port>/demo`щоб це сталося з чудовим проектом під назвою EasyNMT.

<p>
<img src="/articleimages/translatedemof.png?format=webp&height=450" alt="Demo">
</p>
[TOC]

<!--category-- mostlylucid-nmt, EasyNMT,  Neural Machine Translation, Python, FastAPI, Docker, CUDA, PyTorch, Transformers, Helsinki-NLP,  API-->
<datetime class="hidden">2025-11-08T12:30</datetime>

## ЯК ЖЕ, якщо ви тільки-но перевірили, що експропріатор, ви знаєте, є проблема... вона не була зворушена протягом РОКІВ.

Це простий, швидкий спосіб отримати API перекладу без потреби платити за якусь послугу або запустити повний розмір LLM для отримання перекладу (повільно).

### На наших попередніх дописах ми обговорювали, як інтегрувати JestyNMT з програмами ASP.NET для фонового перекладу.

**Але з часом почали з'являтися тріщини.**Прийшов час на щось краще.

**Як завжди на GitHub і все безкоштовно для використання і т.д.**Docker pulls

- ✓ **cpu**: `Reusing loaded model for en->de (3/10 models in cache)`
- ✗ **cpu- min**: `Need to load model for en->fr (3/10 models in cache)`
- **gpu**gpu-min
- **Демонстрація... Пізніше перегляньте демонстрацію сторінки!**Повнофункціональна сторінка демонстрації (здебільшого)
- **(в**або лише корінь)
- **Що нового?**Перш ніж ми перейдемо до швидкого початку гри, ось що робить цю версію зміною гри:

**Основні оновлення (версія 3. 1) - Розвідка і видимість**Створити у v3. 1:

- **Найсвіжіша версія - це грандіозне вдосконалення надійності, швидкодії та розумний вибір моделі!**1.
- **Смарт- модель катування з видимістю**- Посмотрите, что происходит.
- **Журнал XIT кешу**Журнал MISS для кешу
- **Стеження за станом кешу**: Показує відсоток завантаження і завантажені моделі
- **Попередження про евіфікацію**: Чіткі попередження, якщо кеш переповнений, а моделі виселяються.
- **Збільшує місткість**:
  ```
  ====================================================================================================
    🚀 DOWNLOADING MODEL
    Model: facebook/mbart-large-50-many-to-many-mmt
    Family: mbart50
    Direction: en → bn
    Device: GPU (cuda:0)
    Total Size: 2.46 GB
    Files: 6 main files
  ====================================================================================================
  [Progress bars for each file...]
  ====================================================================================================
    ✅ MODEL READY
    Model: facebook/mbart-large-50-many-to-many-mmt
    Translation: en → bn is now available
  ====================================================================================================
  ```

**: Типовий розмір кешу зв' язано з 10 моделями (з 6)**Журналювання за моделюванням пристрою

- **: Ознайомтеся з тим, який спосіб використання GPU/CPU використовує кожна з моделей**2.
- **Покращений поступ звантаження**- Мене більше не цікавить, чи він застряг:
- **Розмір перед звантаженням**:
  ```
  [Pivot] Languages reachable from en: 85 languages
  [Pivot] Languages that can reach bn: 42 languages
  [Pivot] Found 38 possible pivot languages
  [Pivot] Selected pivot: en → hi → bn (both legs verified)
  ```
- **: Показує загальний розмір звантаження (наприклад, " Тотал Розмір: 2. 46 ГБ ")**Кількість файлів
- **: показує кількість файлів для звантаження**Показ пристроїв

**: Показує пристрій призначення (GPU/CPU) у банці**Смужка поступу

- **: Чудовий прогрес tqdm для кожного файла (коли на TTY)**Прапорець завершення
- **: Очистити повідомлення про успіх, якщо модель готова**Приклад виводу
- **3.**:
  ```
  Request: en→bn with opus-mt
  Trying families: ['opus-mt', 'mbart50', 'm2m100']  ✓ All three!
  opus-mt: Failed (model doesn't exist)
  mbart50: Success! (auto-fallback worked)
  ```

**Data- Driven Intesent Pivot Вибір**- Більше ніяких сліпих спроб:

- Логіка кмітливого перетину`Loading mbart50 model on GPU (cuda:0)`
- : знаходить мови, де існують ноги-поворотні лінії BOTH`Model loaded on device: cuda:0`
- Уникає невдалих спроб`Successfully loaded... on GPU (cuda:0)`

**: Не буде намагатися en →bn, якщо es→bn не існує**Приклад для en→bn

- Зворотний пріоритет`en->hi`, `hi->bn`
- : Англійська → Іспанська → Французька → Німецька → Китайська → Російська
- Прозорий ведення журналу`[Pivot] Both legs loaded and cached. Ready to translate.`

**: з'ясувати, чому було обрано або пропущено кожен з поворотів**4.

- Моноширинне автоматичне повернення
- - Більше ніяких подвійних течій:`model_family`Завжди пробувати зворотні результати
- : Навіть якщо сім'я воліє підтримувати пару

### Одна спроба на сім'ю

**: Більше ніяких спроб однієї моделі двічі.**Приклад потоку

- 5.
- Яскравість GPU
- - Завжди знаєш, де твої моделі:
- Кожне завантаження моделі показує:
- Після завантаження підтверджується:

**Повідомлення про успіх містить:**6.

- **Кечування моделі Pivot**- Достатнє повторне використання:
- **Обидві ноги каркасу окремо:**Наступного разу, en→hi або hi →bn потрібні, миттєве кешування!
- **Спорожнити журнал:**7.
- Вибір моделі для перевірки

**- Вже працює в демонстраційному режимі:**За допомогою спадного списку Демонстрація можна обрати opus- mt, mbart50 або m2m100

- Відсотки сервера
- параметр на запит
- Моделі, розташовані окремо сім'єю для миттєвого перемикання
- Основні оновлення (версія 3. 0)
- 1.`requirements-prod.txt`Покращена демонстрація сторінка

**- Готовий до створення інтерактивний інтерфейс:**Повне компонування viewport (100vw/ 100vh) для незахоплюючих перекладів

- **Правильний вибір зі спадними списком (більше немає списку даних- внесків/ даних)**Зміна гарнітури (Operus- MT, mBART50, M2M100)
- **Завантаження динамічної мови на основі вибраної моделі**Прокручувати області виводу для великих перекладів
- **2.**Типові параметри швидкодії
- - "Найменше, наскільки це можливо" поза ящиком:
- GPU

**: увімкнено FP16, BATCH_ SIZE=64, MAX_ INFWYL=1 (додатковий для окремого GPU)**Процесор

- : WEB_ CONCURRENCY=4, MAX_ INFLYPE=4, BATCH_ SIZE=16 (дослідити всі ядра)
- Швидке завершення роботи
- : 5- секундний граційний час очікування (більше не 20- секундне вішання)
- Контейнери зупиняються чисто без страшних повідомлень SIGKILL
- 3.
- Оптимізація розробки збирання

**- Менші, швидші зображення:**Вилучено залежності перевірки (pytest, pytest- cov) з побудови

- **Зберігає ~200МБ на зображення**Зображення процесора: ~8- 10GB (full), ~3- 4GB (мін)
- **Зображення GPU: ~12- 15GB (full), ~6- 8GB (min)**Всі використовувати
- **для мінімального сліду**4.

**Точне тестування і завантаження**- Перевірте все:

- Комплекс тестування API для Live
- (30+ тести) для здоров'я, перекладу, виявлення, відкриття
- k6 завантаження тестування

**з реалістичними типами трафіку**Кросплатформові скрипти перевірки

- `/discover/opus-mt`(Повершель + Баш)
- `/discover/mbart50`Повернення тестів на створення моделей звантажень і перекладу turn
- `/discover/m2m100`Автоматизовані тести на швидку перевірку диму

**5.**Документація з впровадженням

- - Виготовлення-готове з першого дня:
- 4 Сценарії налаштування: Max Tracput, Latency, High Concurrence, Consecurated
- Набір прикладів з налаштуваннями GPU/CPU

**Kubernetes показується з PVC, обмеження ресурсів, перевірки стану здоров'я**Приклади контейнерів Azure

- `scottgal/mostlylucid-nmt:cpu`Завантажити вказівки для перевірки та моніторингу`:latest`Объясняние распространяемых торговых событий
- `scottgal/mostlylucid-nmt:cpu-min`6.
- `scottgal/mostlylucid-nmt:gpu`Три зразкові сім'ї
- `scottgal/mostlylucid-nmt:gpu-min`- Виберіть найкраще для ваших потреб:

**Opus-MT**: 1200+пари, найкраща якість (вимірювання моделей)

- mBART50`latest`, `min`, `gpu`, `gpu-min`: 50 мов, єдина модель 2.4GB, 2.450 пар
- M2M100`20250108.143022`: 100 мов, єдина модель 2.2GB, 9 900 пар
- 7.

**Автоматичний відступ**- Розумно вибирає найкращу модель:

- **Встановити початкову родину (наприклад, Opus- MT для якості)**Автоматично виконувати mBART50/M2M100, якщо пара недоступна
- **Максимальна обкладинка без остаточної якості**8.
- **Відкриття моделі**- Динамічні запити наявні моделі:
- - Всі пари 1200+ з Heback Face

**- Всі пари mBART50**- Всі пари M2M100

- 9.
- Мінімальні зображення

---


## - Менший, гнучкіший простір:

Немає попередньо завантажених моделей (завантажувати на- деменд)

### Постійний кеш, накреслений гучністю

Перемкнути зразкові сім'ї без перебудовування**Десять.**Сховище окремих об' єктів

- Всі варіанти в одному місці:
|-----|-----------------|------|-------------|----------|
| `cpu`(або`latest`) | `scottgal/mostlylucid-nmt:cpu`) - Процесор
| `cpu-min` | `scottgal/mostlylucid-nmt:cpu-min`- Мінімум ЦП
| `gpu` | `scottgal/mostlylucid-nmt:gpu`- GPU з CUDA 12.6
| `gpu-min` | `scottgal/mostlylucid-nmt:gpu-min`- Мінімум GPU

**11.**Правильна версія

- - Всі зображення містять версію дати:
- Мітки з назвою (
- ) завжди вказує на останнє збирання
- Незмінні теґи версій (наприклад,

### ) для окремих споруд

**Повноцінні мітки OCI для стеження за версіями, датами збирання і внесками git**

```bash
docker run -d \
  --name mostlylucid-nmt \
  -p 8000:8000 \
  scottgal/mostlylucid-nmt
```

**12.**

```bash
curl -X POST "http://localhost:8000/translate" \
  -H "Content-Type: application/json" \
  -d '{
    "text": ["Hello, how are you?"],
    "target_lang": "de"
  }'
```

**Останні базові зображення**

```json
{
  "translated": ["Hallo, wie geht es Ihnen?"],
  "target_lang": "de",
  "source_lang": "en",
  "translation_time": 0.34
}
```

### - Покращення безпеки і швидкодії:

Python 3. 12- slim

```bash
docker run -d \
  --name mostlylucid-nmt \
  --gpus all \
  -p 8000:8000 \
  -e EASYNMT_MODEL_ARGS='{"torch_dtype":"fp16"}' \
  scottgal/mostlylucid-nmt:gpu
```

### для зображень процесора (адреси Python 3. 11 можливостей)

CUDA 12. 6

**з Ubuntu 24. 04 для зображень GPU (latest NVIDIA стос)**

```bash
docker run -d \
  --name mostlylucid-nmt \
  -p 8000:8000 \
  -v $HOME/model-cache:/models \
  -e MODEL_CACHE_DIR=/models \
  scottgal/mostlylucid-nmt:cpu-min
```

**PyTorch with CUDA 12.4**

```powershell
docker run -d `
  --name mostlylucid-nmt `
  -p 8000:8000 `
  -v ${HOME}/model-cache:/models `
  -e MODEL_CACHE_DIR=/models `
  scottgal/mostlylucid-nmt:cpu-min
```

**(сумісна з СУДА 12.6)**

```cmd
docker run -d ^
  --name mostlylucid-nmt ^
  -p 8000:8000 ^
  -v %USERPROFILE%/model-cache:/models ^
  -e MODEL_CACHE_DIR=/models ^
  scottgal/mostlylucid-nmt:cpu-min
```

Всі залежності оновлено до останніх безпечних версій

**13.**

```bash
curl http://localhost:8000/healthz
```

Попереджальні попередження про фіксоване амортизацію

## - Запевняю вас у майбутньому:

Вилучено застаріле REFORMERS_ CCHACE (тепер з використанням HF_ HOME)**Сумісний з Transformers v5**Швидкий запуск (5 хвилин)

```
http://localhost:8000/demo/
```

<p>
<img src="/articleimages/translatedemof.png?format=webp&height=800" alt="Demo">
</p>
### Хочеш перекладати?

Ось абсолютний найпростіший спосіб запуску biglucid-nmt:

**Доступні зображення панелі**

- Всі варіанти доступні з
- одне сховище
- з різними мітками:

**Передня частина зображення має бути розміщена так, щоб вона була розміщена у центрі уваги.**

- (або
- 
- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- +GB + GPU з кодом CUDA} ГПУС
- +4GB} GPU minimal, немає заздалегідь завантажених моделей} GPU з об'ємом- картами кешу}

**Мінімальні зображення**

- рекомендуємо для:
- Виробництво з кешем у вигляді об' єму
- Використання mBART50 або M2M100 (великі моделі)

**Зберігати розміри контейнера малими**

- **Гнучкість до заміни моделей сімей без перебудування**Простий запуск (Popus- MT процесор)
  - 1.
  - Тягніть і біжіть:
- **2.**Перекладіть текст:
  - Відповідь:
  - GPU Acceled (10x Fast)

**Потрібний час запуску NVIDIA:**

- **З постійним кешем моделей**Звантажити моделі один раз і залишити їх між перезапусками контейнера:
- **Linux/Mac:**Windows (PowerShell):
- **Вікна (CMD):**Моделі автоматично звантажуються при першому використанні і залишаються у вашому локальному каталозі!

**Перевірка здоров'я:**

- Це п'ятихвилинний швидкий старт!
  - **Для виробництва, конфігурації та додаткових можливостей продовжуйте читати.**Інтерактивна демонстрація сторінка
  - **До служби включено повнофункціональну службу**Інтерактивна сторінка демонстрації
  - **що спрощує перевірку перекладів без написання жодного коду.**Доступ до нього за адресою:
- Демонстраційні можливості

### На сторінці демонстрацій передбачено повноцінне середовище для перевірки перекладів за допомогою:

1.

```javascript
// Example: Translating a 5000-word article
Input: Long article with multiple paragraphs

Step 1: Split by paragraphs (preserves structure)
  → Paragraph 1 (800 chars)
  → Paragraph 2 (1200 chars)
  → Paragraph 3 (600 chars)
  ...

Step 2: Group into ~1000 character chunks
  → Chunk 1: Paragraphs 1-2
  → Chunk 2: Paragraph 3-4
  → Chunk 3: Paragraphs 5-6

Step 3: Translate each chunk sequentially
  → Shows progress: "Translating chunk 1/3..."
  → Shows progress: "Translating chunk 2/3..."
  → Shows progress: "Translating chunk 3/3..."

Step 4: Reassemble with paragraph breaks
  → Final output: Complete translated article with preserved formatting
```

### Вибір мови

**Автозаселення мов зі спадного меню служби**

- Поміняти місцями мови джерела/ призначення одним клацанням
- Підтримує всі 100+ мови, налаштовані у службі
- 2.
- Кмітлива текстова розмітка

**Автоматично виконувати великі текстові входи будь- якого розміру**

- Інтелектуальне розділення абзацами, збереження структури документа
- Переводить назад до речення розділюючись на дуже довгі абзаци
- Показує поступ для багатофункційних перекладів ("Перетворення шматка 2/5 ...")
- Безперервно нагромаджуються шматки з відповідними проміжками.

**3.**

- Виявлення мови
- Визначити мову джерела одним клацанням
- Автоматично заселює спадний список мови джерела
- Робота з текстом до 5000 символів

### 4.

1. **Додаткові параметри**:
   
   - Розмір зерна
   - : Контрольна якість перекладу (1- 10)
   - Вищі значення = кращу якість, але повільніші
   - Нижні значення = швидший прохід

2. **Розділення речень**:
   
   - : увімкнути або вимкнути автоматичне розбиття речень
   - Увімкнено (типовий): розділює довгі тексти на речення для кращої якості
   - Вимкнено: перекладає весь текст як один блок (швидше для коротких текстів)
   - 5.

3. **Статистика реального часу**:
   
   - Час перекладу
   - : Показує поточну тривалість перекладу на стороні сервера
   - Кількість символів
   - : Підрахуйте скільки набираєте

### Індикатор стану

: Бездіяльний → Трансляція → Виконано/ Помилка

- **6.**Знаходження моделі сім'ї
- **Використання пар перекладів для кожної зразкової сім' ї:**Opus-MT
- **: 1200+пари мов**mBART50
- **: 50 мовами, 2.450 пар**M2M100

: 100 мовами, 9700 пар`/demo/`Визначити, які пари мов доступні перед перекладом

## Як працює текстова розшифровка

Демонстрація реалізує інтелектуальний фрагмент тексту на стороні клієнта:[Чому слід використовувати демонізм?](https://github.com/UKPLab/EasyNMT)Швидке тестування[Перевіряти переклади без коду запису](https://www.mostlylucid.net/blog/category/EasyNMT)Перевірити доступність пари мов

Порівняти якість перекладу з різними розмірами променя

1. **Тестові випадки ребер (емоджі, символи, спеціальні символи)**Допомога у розробці
2. **Див. точний формат запиту/ репонентів API**Перевіряти стан служби перед об'єднанням
3. **Перевірка швидкодії з різними розмірами тексту**Відкрити наявні гарні сім'ї
4. **Довідка клієнта**Показує відповідні шаблони використання API
5. **Демонструє роботу з помилками (429, виявлення мови)**Приклад реалізації шматків
6. **Повторна логіка реального світу**Приклад використання*Простий переклад*.
7. **Вставте текст: "Привіт, як справи сьогодні?"**Вибір мети: німецька
8. **Натисніть " Транзиту "**Результат: "Hallo, welle geht es Ihnen hute?"

## Довгий переклад документа

Вставити весь допис блогу (5000 слів)**Демонстрація автоматично зрізає її на частини, які можна налаштувати**Показує поступ під час перекладу кожного шматка

### Повертає документ повністю перекладений

Виявлення мови**Вставити текст невідомою мовою**Натисніть " Вилучити мову "

#### Демонстрація ідентифікувати мову і оновлення

- **Готовий до перекладу негайно**Технічні подробиці
- **Сторінка демонстрації:**Самодостатнє
- **: Окремий HTML файл з вбудованим JavaScript**Нуль залежностей
- **: Не потрібно зовнішніх бібліотек**Приязний до мобільнихComment
- **: Конструкція працює на всіх пристроях.**Виробництво готове
- **: У ваших програмах можна використовувати ту саму логічну логіку.**Доступ до живої демонстрації в

#### у вашому запущеному екземплярі!

- **Проблеми з легкою пам'яттю**Тепер це не злине на
- **EasyNMT**і я будую.
- **МАЛО проектів, що використовують його**
- **Він просто довго в зубах, так що... які у нас проблеми?**Боже, їх багато.
- **EasyNMT було побудовано майже десять років тому.**Технологія просунулася... до того, що вона ніколи не мала бути виробничою системою.
- **Унизу подаємо деякі спірні питання:**Невдаха.

#### Він не розрахований на те, щоб відновитися від проблем, так часто його просто не видно.

- **Це SUER PICKY щодо їх вводу.**Емоційки, символи, навіть числа можуть спантеличити їх.
- **Він не призначений для будь-якого навантаження.**Дивіться вище.
- **Вона ніколи не була створена.**Він не призначений для оновлення своїх моделей.
- **або бути (легко) побудований з вбудованими моделями.**Його речовий матеріал GPU CUDA давній
- **Так повільніше, ніж має бути.**Ти нічого не можеш полагодити.
- **Код Python на експропріаторі, але знову**не чудовий

**Ніяких відштовхувань чи чергування.**Надсилайте забагато запитів, і він просто з'являється.`MODEL_FAMILY`Ніякої упертості.

```bash
# Opus-MT (default, best quality)
MODEL_FAMILY=opus-mt

# mBART50 (50 languages, single model)
MODEL_FAMILY=mbart50

# M2M100 (100 languages, broadest coverage)
MODEL_FAMILY=m2m100
```

### Когда всё идет не так, ты летаешь слепой.

Вирішення: здебільшогоLucid-NMT**Тому... я вирішив побудувати новий та покращений THENMT, зараз**umcid-nmt

****

1. Це не просто латка робота; це повний перепис з використанням виробництва.`MODEL_FAMILY`Ось що робить це кращим:`opus-mt`Багатомодерна підтримка сім'ї
2. Зараз підтримується здебільшого Lucid- NMT
3. три сім' ї моделей перекладу
4. , даючи вам гнучкість, що базується на ваших потребах:

**Opus- MT (Helsinki- NLP) - типовий**

```bash
# Set primary to Opus-MT (best quality)
MODEL_FAMILY=opus-mt
AUTO_MODEL_FALLBACK=1
MODEL_FALLBACK_ORDER=opus-mt,mbart50,m2m100

# Request Ukrainian → French
# 1. Try Opus-MT first (not available)
# 2. Automatically fall back to mBART50 (available!)
# 3. Translation succeeds with mBART50
```

**Обкладинка:**

- **1200+пари перекладів для 150+ мов**Архітектура:
- **Розділити модель на напрямок перекладу**Якість:
- **Найкраща якість перекладу**Випадок використання:
- **Виготовлення перекладів, де якість має значення**Розмір моделі:

**300- 500 Мб на напрямок**

```bash
# Enable auto-fallback (default: enabled)
AUTO_MODEL_FALLBACK=1

# Set fallback priority (default: opus-mt → mbart50 → m2m100)
MODEL_FALLBACK_ORDER="opus-mt,mbart50,m2m100"

# Disable for strict single-family mode
AUTO_MODEL_FALLBACK=0
```

Приклад:

### Англійська → Німецька - інша модель, ніж німецька → English

1. **mBART50 (лицем)**Обкладинка:
2. **50 мов, повний переклад**Архітектура:
3. **Одна багатомовна модель**Якість:
4. **Добра якість, особливо для головних мов.**Випадок використання:
5. **Конструкція простору або багато пар мов**Розмір моделі:
6. **~2. 4GB (single модель для всіх 50 мов)**Переваги:
7. **Одна модель керує 2 450 парами перекладів**M2M100 (лицем)
8. **Обкладинка:**100 мов, повний переклад
9. **Архітектура:**Одна багатомовна модель
10. **Якість:**Добра якість з найширшим покриттям мови
11. **Випадок використання:**Максимальна обкладинка мови`-min`Розмір моделі:

## ~2. 2GB (single модель для всіх 100 мов)

Переваги:

### Одна модель керує 9 900 парами перекладів

**Перемикання просте**

- - Просто наведите.
- змінна середовища:
- Автомодельована сім'я - нове!

**Однією з найсильніших нових рис є**

- автоматичний спад між моделями сімей
- 
- Це забезпечує максимальну оцінку пари мов під час приготувань до перекладу.

**Як це працює:**Ви встановили основний

- **(e.g.,**для найліпшої якості)
- **Коли ви хочете мати пару, яка б перекладала, якої немає в головній сім'ї.**Система автоматично перевіряє наступну сім'ю у порядку повернення
- **Це продовжується до того часу, доки не буде знайдено відповідну модель**Скрипт прикладу:

Користі:

### Максимальне покриття:

**Підтримка 100+ мов без керування декількома розповсюдженнями**

- Пріоритет якості:
- Завжди використовуйте найкращу досяжну модель для кожної пари
- Нульове налаштування:
- **Працює автоматично, не потрібно втручання вручну**

**Прозоре ведення журналу:**

- Дивіться, яку модель сім'ї було використано для кожного перекладу
- Налаштування:
- Ця можливість ідеально пасує до середовища виробництва, у якому ви бажаєте максимального покриття без втрати якості!
- Вдосконалення ключів

**Багатомодельована підтримка сім' ї**

```bash
# NMT: Fits on a USB stick
du -sh model-cache/
2.5G    model-cache/

# LLM: Needs serious storage
du -sh llama-models/
140G    llama-models/
```

### - Оберіть варіант Opus- MT (1200+пари), mBART50 (50 мов), або M2M100 (100 мов).

**Кінцеві точки відкриття моделі**

- - Динамічні запити для кожної сім'ї.
- Обробка обробки вхідних даних
- - Емоджі?
- Числа?

**Символи?**

- Давай.
- До служби тепер включено повнофункціональну вимову та маску символів.
- Запит щодо черги завдань і зворотного друку
- - Побудовано на основі семафри чергуються з розумними оцінками щодо повторних спроб.

**Кечування моделей LRU**

- Автоматично керує VRAM, виганяючи старі моделі, якщо кеш повний.
|--------|------|------|
Сучасна підтримка CUDA
- Використовує PyTorch з CUDA 12. 6, підтримує покращення швидкості 2x для FP16/BF16.
Виробництво-готове узгоджування
- Перевірка здоров'я, зонди Очищення, стан кешу, вирубка лісозаготівель.
Милосердне завершення роботи

### - Ніяких осиротілих запитів чи зіпсованих станів.

**Сумісний з EasyNMT API**

- - Заміна існуючих інтеграцій.
- Повернення перекладу Pivot
- - Якщо пара мов недоступна, автоматично прокладає шлях через англійську (або обраний вами поворот).
- Мінімальний об' єм зображень
- - Нову

**Варіанти з кешем на основі об' єму для менших значень.**

- ⚠️ Sometimes adds interpretations not in original
- ⚠️ Quality varies with prompt phrasing
- ⚠️ Can be "creative" with technical terms
- ⚠️ Needs careful prompt engineering
- ⚠️ Unpredictable with edge cases

**Чому НМТ над LLMs для перекладу?**

```text
Input: "The API returns a 429 status code when rate limited."

NMT (Opus-MT): "Die API gibt einen 429-Statuscode zurück, wenn sie ratenbegrenzt ist."
(Accurate, preserves technical terms)

LLM (might do): "Die API sendet den Fehlercode 429, wenn zu viele Anfragen gestellt werden."
(Interprets rather than translates, adds context not in original)
```

### Ви можете запитати: "Навіщо використовувати віддану службу NMT, коли LLMs на зразок GPT-4, Claude або Llama може перекладати?" Чудове питання.

**Ось реальна перевірка на основі використання виробництва:**

- Швидкість: швидкість 10- 100x швидче
- NMT (здебільшого вимірюваного- nmt):
- ЦП: ~0. 3- 1. 0 секунд на речення
- GPU (FP16): ~0.05- 0. 2 секунд на речення
- Пакетна обробка: 50+ речення/секунда у GPU
- LLMs:

**GPT- 4: 3- 10 секунд на запит (покоління латок + створення)**

- Llama 3 70B: 5- 15 секунд на речення (локальне)
- Claude 3: 2- 8 seconds на запит (permission)
- Справжній приклад:
- Переклад допис блогу 1000 слів:
- threecid-nmt (GPU)

### : 5- 10 секунд

GPT-4 API**: 30- 60 секунд**Локальна Llama 70B

- : 2- 5 хвилин
- Коли ви автоматично перекладаєте сотні блогів на 12+нонгів, то різниця у швидкості - MASSIVE.
- Розмір моделі: 500MБ проти 140GB
- Моделі NMT:

Opus- MT (у напрямку): 300- 500MB

**mBART50 (всі 50 мов): 2. 4GB**M2M100 (всі 100 мов): 2. 2GB

## Загалом для 100+ мов: ~2. 2GB

```mermaid
flowchart LR
    A[HTTP Client] --> B[API Gateway]
    B --> C[Translation Endpoint]
    C --> D{Has Capacity?}
    D -->|Yes| E[Translation Service]
    D -->|No| F[Queue with 429]
    F --> E
    E --> G[Process Pipeline]
    G --> H[Get Model from Cache]
    H --> I[Translate]
    I --> J[Return Response]
    J --> A
```

LLMs:

1. **Llama 3 8B: ~16GB**Llama 3 70B: ~140GB
2. **Mixtral 8x7B: ~90GB**GPT- 4: недоступний для самопідтримання
3. **Ефект зберігання:**Вимоги виконавців: Лептоп/ Ферма сервера
   - **Деляція процесора NMT:**Дуже добре працює: над двома ядрами процесора, 4GB RAM
   - **Зображення Docker: 1,5- 2, 5GB**Підсилення: лише процесор, не потрібен GPU`Retry-After`Вартість: 10- 20/ місячний VPS
4. **Вимоги LLM:**Llama 3 70B: потребує 80GB+ VRAM (A100 GPU)
   - Менші моделі 7Б- 13Б: Мінімальний об' єм пам' яті 16- 32 ГБ
   - Вартість API: 0. 03- 0. 30 на 1000 марок (додається швидко!)
   - Самопідтримка: $ 1000+/місяця для серйозного GPU
   - Порівняння справжніх витрат для 10 000 перекладів блогу:
5. **Д_ д. д. д. д. д. д. д. д. д. д. д. д. д. д.** здебільшого musicid-nmt (CPU)} $20/місяця VPS} 2/3 години}
   -  meanslucid-nmt (GPU) сяє/місяця GPU VPS} 15-30 хвилин
   - +GPE-4 API} $50-300} 8-15 годин
   - +300 + 6-00 годин
6. **♪ Local Llama 70B} $0+/місяцеве обладнання} 20-40 годин ♪**Якість: Purpose-Built vs General- Purpose

**Міць NMT:**Навчені спеціально для перекладу`Retry-After`Відповідна якість (те саме значення, що і вхід = той самий вивід)

## Немає " галюцинацій" - чистого перекладу

### Визначає технічний вміст, код, добре форматування

Не потрібно негайної інженерії

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant Queue
    participant Translator
    participant Cache
    participant Model

    Client->>API: POST /translate
    API->>Queue: Acquire slot

    alt Queue has space
        Queue-->>API: Slot acquired
        API->>Translator: Process translation
        Translator->>Translator: Sanitize input
        Translator->>Translator: Split sentences
        Translator->>Translator: Chunk text
        Translator->>Translator: Mask symbols
        Translator->>Cache: Get model (en→de)

        alt Cache hit
            Cache-->>Translator: Return cached model
        else Cache miss
            Cache->>Model: Load from Hugging Face
            Model-->>Cache: Pipeline loaded
            Cache->>Cache: Evict old if at capacity
            Cache-->>Translator: Return model
        end

        Translator->>Model: Translate batches
        Model-->>Translator: Translations
        Translator->>Translator: Unmask symbols
        Translator->>Translator: Post-process
        Translator-->>API: Translations
        API->>Queue: Release slot
        API-->>Client: 200 OK + translations
    else Queue full
        Queue-->>API: Overflow error
        API-->>Client: 429 Too Many Requests\nRetry-After: X seconds
    end
```

### Зусилля LLM:

Скрипт прикладу:

```mermaid
graph LR
    A[Raw Input] --> B{Sanitize?}
    B -->|Yes| C[Check Noise]
    B -->|No| D[Split Sentences]
    C -->|Is Noise| Z[Return Placeholder]
    C -->|Valid| D

    D --> E[Enforce Max Length]
    E --> F[Chunk for Batching]
    F --> G{Symbol Masking?}

    G -->|Yes| H[Mask Digits/Punct/Emoji]
    G -->|No| I[Translate]
    H --> I

    I --> J{Direct Model?}
    J -->|Available| K[Direct Translation]
    J -->|Not Available| L{Pivot Fallback?}

    L -->|Yes| M[src→en→tgt]
    L -->|No| Z
    K --> N[Unmask Syis robust input handling. Here's what happens:

**Noise Detection:**
- Strips control characters (except \t, \n, \r)
- Checks minimum character count (default: 1)
- Calculates alphanumeric ratio (default: must be ≥20%)
- Rejects pure emoji, pure punctuation, or pure whitespace

**Symbol Masking:**
Why mask symbols? Translation models are trained on text, not emoji or special symbols. These can confuse them or get mangled. So we:

1. Extract all digits, punctuation, and emoji as contiguous runs
2. Replace them with sentinel tokens: `⟪MSK0⟫`, `⟪MSK1⟫`, etc.
3. Translate the masked text
4. Restore the original symbols in their positions

Example:
```

Input:  "Hello 👋 world! Price: $99.99"
Коли використовувати кожен
(👋)        (!)      (:)    ($99.99)

```

**Post-Processing:**
After translation, we remove "symbol loops" - repeated symbols that weren't in the source:

```

Використовувати NMT (здебільшого вимірюваного- nmt), якщо:
Вам потрібен послідовний, швидкий переклад у масштабі
Бюджет має значення (збереження або високий об' єм)

```

### Sentence Splitting & Chunking

Long texts get split intelligently:

```mermaid
graph TD
    A[Long Text] --> B[Split on . ! ? …]
    B --> C{Sentence > 500 chars?}
    C -->|Yes| D[Split on word boundaries]
    C -->|No| E[Keep sentence]
    D --> E

    E --> F[Group into chunks ≤900 chars]
    F --> G[Translate each chunk]
    G --> H[Join with space]

```

Ви перекладаєте технічний вміст, код, структуровані дані

- Вам потрібен детермінований вивід (те саме вхід = той самий вивід)
- Ви хочете працювати на процесорі або на малому обладнанні
- Ви будуєте автоматичні транспортні труби для перекладу

### Використовувати LLM, якщо:

Вам потрібна творча адаптація, а не буквальний переклад

```mermaid
stateDiagram-v2
    [*] --> CheckCache
    CheckCache --> CacheHit: Model exists
    CheckCache --> CacheMiss: Model not loaded

    CacheHit --> MoveToEnd: Update LRU order
    MoveToEnd --> ReturnModel

    CacheMiss --> CheckCapacity
    CheckCapacity --> LoadModel: Space available
    CheckCapacity --> EvictOldest: Cache full

    EvictOldest --> MoveToCPU: Free VRAM
    MoveToCPU --> ClearCUDA: torch.cuda.empty_cache()
    ClearCUDA --> LoadModel

    LoadModel --> AddToCache
    AddToCache --> ReturnModel
    ReturnModel --> [*]
```

**Контекстні та культурні нюанси важливіші, ніж швидкість**

- Ви робите переклади низької кількості, однократні
- Вам слід перекласти + підсумувати + переписати на один крок
- Ви в порядку зі змінними витратами і повільнішою обробкою
- Підсумок
- for

### Автоматний переклад блогу

(мій випадок використання), NMT є ясним переможцем:

```python
# Semaphore limits concurrent translations
MAX_INFLIGHT = 1  # On GPU, 1 at a time for efficiency
MAX_QUEUE_SIZE = 1000  # Up to 1000 waiting

# When full:
# - Returns 429 Too Many Requests
# - Includes Retry-After header
# - Estimates wait time based on average duration
```

Перекладає дописи 100+ блогів на 12 мов у ~30 хвилин (GPU)

```
avg_duration = 2.5 seconds (tracked with EMA)
waiters = 100
slots = 1
estimated_wait = (100 / 1) * 2.5 = 250 seconds
clamped = min(250, 120) = 120 seconds
Retry-After: 120
```

### Запускається на $50/місяць VPSName

Послідовна якість для всіх дописів

```mermaid
graph LR
    A[Ukrainian Text] --> B{Direct uk→fr?}
    B -->|Exists| C[Translate Directly]
    B -->|Missing| D[Pivot via English]

    D --> E[uk→en]
    E --> F[en→fr]
    F --> G[French Result]
    C --> G

```

Загальне налаштування: один контейнер панелі

## Спроба скористатися LLM коштувала б сотні доларів на місяць у платі за API або потребувала б сервер GPU на $1.

Лише різниця швидкості робить NMT єдиним практичним вибором для створення транспортних трубопроводів.

### ТЛ; ДР:

NMT побудовано з метою перекладу, працює на звичайному апаратному забезпеченні, він є на 10- 100x швидшим за LLM. Якщо вам потрібно швидкий, послідовний, ефективних результатів перекладу на шкалі, NMT перехоплює руки.

```python
# src/core/cache.py
from collections import OrderedDict
import torch

class LRUPipelineCache:
    """LRU cache that automatically cleans up GPU memory when evicting models."""

    def __init__(self, capacity: int):
        self.cache = OrderedDict()  # Maintains insertion order
        self.capacity = capacity

    def get(self, key: str):
        """Get model from cache, moves it to end (most recently used)."""
        if key not in self.cache:
            return None
        self.cache.move_to_end(key)  # Mark as recently used
        return self.cache[key]

    def put(self, key: str, value):
        """Add model to cache, evicting oldest if at capacity."""
        if key in self.cache:
            self.cache.move_to_end(key)
        else:
            self.cache[key] = value

        # If cache is full, evict the oldest model
        if len(self.cache) > self.capacity:
            oldest_key, oldest_pipeline = self.cache.popitem(last=False)

            # MAGIC: Move evicted model to CPU to free GPU memory
            try:
                oldest_pipeline.model.to("cpu")
                if torch.cuda.is_available():
                    torch.cuda.empty_cache()  # Tell GPU to release memory
                logger.info(f"Evicted {oldest_key}, freed GPU memory")
            except Exception as e:
                logger.warning(f"Failed to clean GPU memory: {e}")
```

**Огляд архітектури**

- `OrderedDict`Потік запиту є простим:
- **Клієнт**надсилає запит на переклад до шлюзу API (Guni жолудів + працівників Uvichor)
- **Шлюз API**Шлях до точки завершення перекладу
- **Перевірка місткості**: Система перевіряє, чи може вона виконувати запит

### Так.

→ Запит негайно відправляється до перекладацької служби

```python
# src/services/model_manager.py
def get_pipeline(self, src: str, tgt: str):
    """Try to get translation model, with automatic fallback to other providers."""

    # Determine which model families support this language pair
    families_to_try = []

    if config.AUTO_MODEL_FALLBACK:
        # Try families in priority order: opus-mt → mbart50 → m2m100
        for family in config.MODEL_FALLBACK_ORDER.split(","):
            if self._is_pair_supported(src, tgt, family.strip()):
                families_to_try.append(family.strip())

    # Try each family until one succeeds
    last_error = None
    for family in families_to_try:
        try:
            model_name, src_lang, tgt_lang, _ = self._get_model_name_and_langs(src, tgt, family)

            if family != config.MODEL_FAMILY:
                logger.info(f"Using fallback '{family}' for {src}->{tgt}")

            # Load the model from HuggingFace
            pipeline = transformers.pipeline(
                "translation",
                model=model_name,
                device=device_manager.device_index,
                src_lang=src_lang,
                tgt_lang=tgt_lang
            )

            self.cache.put(f"{src}->{tgt}", pipeline)
            return pipeline

        except Exception as e:
            last_error = e
            logger.warning(f"Family '{family}' failed for {src}->{tgt}: {e}")
            continue  # Try next family

    # All families failed
    raise ModelLoadError(f"{src}->{tgt}", last_error)
```

**Ні**

- **→ Запит до черги, клієнт отримує HTTP 429 з**заголовок
- **Служба перекладу**обробити запит за допомогою трубопроводу:
- **Вхідне встановлення і розбиття речень**Маскування символів (emojis, спеціальні символи)
- **Переклад за допомогою кешованих моделей**Символ, який розмасшує і остаточно обробляє

### Кеш моделей

(LRU) постачає моделі перекладу:

```python
# src/services/queue_manager.py
import asyncio
from contextlib import asynccontextmanager

class QueueManager:
    """Manages request queuing and backpressure."""

    def __init__(self, max_inflight: int, max_queue: int):
        self.semaphore = asyncio.Semaphore(max_inflight)  # Limit concurrent translations
        self.max_queue_size = max_queue
        self.waiting_count = 0
        self.inflight_count = 0
        self.avg_duration_sec = 5.0  # Exponential moving average

    @asynccontextmanager
    async def acquire_slot(self):
        """Try to get a translation slot, track metrics, handle queueing."""

        # Check if queue is too full
        if self.waiting_count >= self.max_queue_size:
            # Calculate how long client should wait before retrying
            retry_after = self._estimate_retry_after()
            raise QueueOverflowError(self.waiting_count, retry_after)

        self.waiting_count += 1
        try:
            # Wait for available slot (this is the queue!)
            await self.semaphore.acquire()
            self.waiting_count -= 1
            self.inflight_count += 1

            start_time = time.time()
            yield  # Let the translation happen

            # Update average duration for retry-after estimates
            duration = time.time() - start_time
            alpha = config.RETRY_AFTER_ALPHA  # Smoothing factor (0.2)
            self.avg_duration_sec = alpha * duration + (1 - alpha) * self.avg_duration_sec

        finally:
            self.inflight_count -= 1
            self.semaphore.release()

    def _estimate_retry_after(self) -> int:
        """Smart calculation: how many waiting / how many slots * avg time per request."""
        if self.inflight_count == 0:
            return config.RETRY_AFTER_MIN_SEC

        # If 10 people waiting and 2 slots available, and each takes 5 seconds:
        # retry_after = (10 / 2) * 5 = 25 seconds
        retry_sec = (self.waiting_count / self.semaphore._value) * self.avg_duration_sec

        # Clamp between min and max
        return max(
            config.RETRY_AFTER_MIN_SEC,
            min(int(retry_sec), config.RETRY_AFTER_MAX_SEC)
        )
```

**Удар кешу → Швидка відповідь**

- **Не вистачає кешу → Завантаження з вузла**Повноцінний кеш → Автоматичні старі моделі, прозора пам' ять CUDA`max_inflight`)
- **Відповідь** (`@asynccontextmanager`return to client
- **Дизайн ключів:**Механізм зворотного друку (queue + HTTP 429) запобігає аварійним завершенням під час завантаження.
- **Якщо перевищено, запити з черги послуг замість того, щоб вмерти, надають клієнтам кмітливих спроб через**заголовки.
- **Як це працює.**Запитувати потоку

### Коли надходить запит на переклад, ось що станеться:

Вхідна лінія трубопроводу

```python
# src/utils/symbol_masking.py
import re

def mask_symbols(text: str) -> tuple[str, dict[str, str]]:
    """Replace special symbols with placeholders before translation."""

    originals = {}
    masked_text = text
    placeholder_counter = 0

    # Pattern: Match emojis, symbols, special punctuation
    # \U0001F300-\U0001F9FF = emoji range
    # [\u2600-\u26FF\u2700-\u27BF] = misc symbols
    symbol_pattern = re.compile(
        r'[\U0001F300-\U0001F9FF\u2600-\u26FF\u2700-\u27BF'
        r'\u00A9\u00AE\u2122\u2139\u3030\u303D\u3297\u3299]+'
    )

    for match in symbol_pattern.finditer(text):
        symbol = match.group()
        placeholder = f"__SYMBOL_{placeholder_counter}__"
        originals[placeholder] = symbol
        masked_text = masked_text.replace(symbol, placeholder, 1)
        placeholder_counter += 1

    return masked_text, originals

def unmask_symbols(text: str, originals: dict[str, str]) -> str:
    """Restore original symbols after translation."""
    for placeholder, original in originals.items():
        text = text.replace(placeholder, original)
    return text
```

**Служба використовує складний багатосмуговий трубопровод для обробки безладного тексту реального світу:**

```python
# Before translation:
text = "Hello! 👋 Check out this cool feature 🚀"

# Mask symbols:
masked, originals = mask_symbols(text)
# masked = "Hello! __SYMBOL_0__ Check out this cool feature __SYMBOL_1__"
# originals = {"__SYMBOL_0__": "👋", "__SYMBOL_1__": "🚀"}

# Translate the masked text:
translated = translate(masked, "de")  # → "Hallo! __SYMBOL_0__ Schau dir diese coole Funktion an __SYMBOL_1__"

# Unmask symbols:
final = unmask_symbols(translated, originals)
# final = "Hallo! 👋 Schau dir diese coole Funktion an 🚀"
```

**ДЗ: "ось світ має значення MSK0}МСК1 +МСК2 +МСК3"**

- **Джерело: "Привіт світ."**Поганий переклад: "Hola mundo!!!!!!!!!
- **Очищено: "Hola mundo" # Прибирає!!!**Забезпечення:`👋`Моделі не задушуються великими входами.`__SYMBOL_0__`Ми можемо пакетизувати ефективно
- **Контекст зберігається у межах**Керування кешуванням і пам'яттю моделей

### Кеш LRU є кмітливим щодо пам' яті GPU:

Чому це є важливим:

```python
# src/utils/text_processing.py
def chunk_sentences(sentences: list[str], max_chars: int = 900) -> list[list[str]]:
    """Group sentences into chunks that fit within model's max input length."""

    chunks = []
    current_chunk = []
    current_length = 0

    for sentence in sentences:
        sentence_len = len(sentence)

        # If this sentence alone is too long, it goes in its own chunk
        if sentence_len > max_chars:
            if current_chunk:
                chunks.append(current_chunk)
                current_chunk = []
                current_length = 0
            chunks.append([sentence])
            continue

        # If adding this sentence exceeds limit, start new chunk
        if current_length + sentence_len + 1 > max_chars:
            chunks.append(current_chunk)
            current_chunk = [sentence]
            current_length = sentence_len
        else:
            current_chunk.append(sentence)
            current_length += sentence_len + 1  # +1 for space

    # Don't forget the last chunk!
    if current_chunk:
        chunks.append(current_chunk)

    return chunks

def split_sentences(text: str, max_sentence_chars: int = 500) -> list[str]:
    """Split text into sentences, enforcing max length."""

    # Split on common sentence terminators
    sentences = re.split(r'([.!?…]+\s+)', text)

    result = []
    for sentence in sentences:
        if not sentence or sentence.isspace():
            continue

        # If sentence is too long, split on word boundaries
        if len(sentence) > max_sentence_chars:
            words = sentence.split()
            current = []
            current_len = 0

            for word in words:
                if current_len + len(word) + 1 > max_sentence_chars:
                    result.append(' '.join(current))
                    current = [word]
                    current_len = len(word)
                else:
                    current.append(word)
                    current_len += len(word) + 1

            if current:
                result.append(' '.join(current))
        else:
            result.append(sentence.strip())

    return result
```

**Пам' ять GPU є цінною**

- **Моделі перекладу - 300- 500 МБ на кожен**Завантаження моделей є повільним (1- 3 секунди)`.!?…`Ми тримаємо 6 найсвіжіших моделей гарячими.
- **Старі моделі автоматично виселяють.**Черга & зворотного друку
- **Замість того, щоб завершувати роботу під навантаженням, черги служб просять:**Оцінка повторення є розумною:
- **Повернення до перекладу Pivot**Не всі пари мов мають прямі моделі гри на обличчі.

### Разрешение?

Pivot через англійську:

```python
# src/services/model_discovery.py
import httpx
from datetime import datetime, timedelta

class ModelDiscoveryService:
    """Discovers available translation models with 1-hour cache."""

    def __init__(self):
        self._cache = {}  # Cache results to avoid hammering HuggingFace API
        self._cache_ttl = timedelta(hours=1)
        self._hf_api_base = "https://huggingface.co/api/models"

    async def discover_opus_mt_pairs(self, force_refresh: bool = False):
        """Query HuggingFace for all Helsinki-NLP Opus-MT models."""

        cache_key = "opus-mt"

        # Check cache first
        if not force_refresh and cache_key in self._cache:
            cached_data, cached_time = self._cache[cache_key]
            if datetime.now() - cached_time < self._cache_ttl:
                return cached_data  # Cache hit!

        # Cache miss - query HuggingFace API
        async with httpx.AsyncClient() as client:
            response = await client.get(
                self._hf_api_base,
                params={
                    "author": "Helsinki-NLP",
                    "search": "opus-mt",
                    "limit": 1000
                },
                timeout=30.0
            )
            models = response.json()

        # Extract language pairs from model names
        # Example: "Helsinki-NLP/opus-mt-en-de" → ("en", "de")
        pairs = []
        for model in models:
            model_id = model.get("modelId", "")
            if model_id.startswith("Helsinki-NLP/opus-mt-"):
                # Extract the language codes after "opus-mt-"
                lang_part = model_id.replace("Helsinki-NLP/opus-mt-", "")
                if "-" in lang_part:
                    src, tgt = lang_part.split("-", 1)
                    pairs.append({"source": src, "target": tgt})

        # Cache the results
        self._cache[cache_key] = (pairs, datetime.now())

        return pairs
```

**Це подвоює спізнення, але забезпечує покриття всіх пар мов, які підтримуються.**

- **Глибокий об' єм коду: придатні для зміни можливості** (`httpx`Давайте дослідимо деякі з найцікавіших частин бази коду!
- **Це справжні виробничі моделі, які роблять службу стійкою і ефективною.**У кожному фрагменті містяться пояснення, що відповідають розробникам, що не належать до Python.
- **1.**Кмітливий кеш LRU з керування пам'яттю GPU`en`Однією з найкрутіших можливостей є кеш з кмітливою моделлю, який знає як обробляти пам' ять GPU:`de`Що тут відбувається?`Helsinki-NLP/opus-mt-en-de`
- **: Як звичайний словник, але пам'ятайте про порядок, який було додано**LRU (Найменш недавно використана)

### : Коли кеш переповнений, викиньте модель, яка не використовується у найдовший час

Очищення GPU

```python
# src/core/device.py
import torch

class DeviceManager:
    """Smart device selection with GPU auto-detection."""

    def __init__(self):
        self.use_gpu = self._should_use_gpu()
        self.device_index = self._resolve_device()
        self.device_str = "cpu" if self.device_index < 0 else f"cuda:{self.device_index}"

        # Auto-configure parallel translation slots based on device
        if self.device_index >= 0:
            # GPU: Run translations serially to avoid VRAM fragmentation
            self.max_inflight = 1
        else:
            # CPU: Can handle multiple translations in parallel
            self.max_inflight = config.MAX_WORKERS_BACKEND

        self._log_device_info()

    def _should_use_gpu(self) -> bool:
        """Check if GPU should be used."""
        if config.USE_GPU.lower() == "false":
            return False
        if config.USE_GPU.lower() == "true":
            return torch.cuda.is_available()
        # "auto" mode: use GPU if available
        return torch.cuda.is_available()

    def _resolve_device(self) -> int:
        """Returns device index: -1 for CPU, 0+ for CUDA."""
        if not self.use_gpu:
            return -1

        # Check if specific CUDA device requested
        if config.DEVICE and config.DEVICE.startswith("cuda:"):
            device_num = int(config.DEVICE.split(":")[1])
            return device_num

        return 0  # Use first GPU

    def _log_device_info(self):
        """Log device information at startup."""
        if self.device_index >= 0:
            gpu_name = torch.cuda.get_device_name(self.device_index)
            vram_gb = torch.cuda.get_device_properties(self.device_index).total_memory / 1e9
            logger.info(f"Using GPU: {gpu_name} ({vram_gb:.1f}GB VRAM)")
            logger.info(f"Max inflight translations: {self.max_inflight} (GPU mode)")
        else:
            cpu_count = os.cpu_count()
            logger.info(f"Using CPU ({cpu_count} cores)")
            logger.info(f"Max inflight translations: {self.max_inflight} (CPU mode)")

# Global singleton instance
device_manager = DeviceManager()
```

**: Виселяючи модель, ми явно переносимо її до процесорної пам' яті і наказуємо GPU випускати свої ресурси**

- **Чому це важливо**: Без цього, пам'ять GPU заповнювалась б і заповнилась б після завантаження 2-3 моделей!
- **2.**Повернення до автоматичної моделі сім' ї`max_inflight=1`Ця кмітлива можливість автоматично перевіряє декілька постачальників комп' ютерної моделі, якщо перша пара не має потрібної пари мов:`max_inflight=4`Що тут відбувається?
- **Ланцюжок зворотного зв' язку**: Якщо Opus-MT не має українською → французькою, спробуйте автоматично mBART50, то M2M100`DEVICE=cuda:1`
- **Без втручання вручну**: Користувачі просто вимагають перекладу і отримують найкращу модель
- **Обробка помилок**: Якщо всі сім'ї зазнають невдачі, ми помиляємося з останньою причиною невдачі.

### Кмітливе кешування

: Успішні моделі захаращуються ключем до мови

```python
# Snippet from QueueManager showing EMA calculation
def update_avg_duration(self, new_duration: float):
    """Update average duration using exponential moving average."""

    # EMA formula: new_avg = α × new_value + (1 - α) × old_avg
    # α = smoothing factor (0.0 to 1.0)
    #   - Higher α = more weight to recent values (faster adaptation)
    #   - Lower α = more weight to historical values (more stable)

    alpha = 0.2  # 20% weight to new value, 80% to historical

    self.avg_duration_sec = (
        alpha * new_duration +
        (1 - alpha) * self.avg_duration_sec
    )
```

**3.**

```python
# Initial average: 5.0 seconds
# New request takes: 10.0 seconds

# EMA calculation:
new_avg = 0.2 * 10.0 + 0.8 * 5.0
        = 2.0 + 4.0
        = 6.0 seconds

# Next request takes: 3.0 seconds
new_avg = 0.2 * 3.0 + 0.8 * 6.0
        = 0.6 + 4.8
        = 5.4 seconds
```

**Запит у чергу з Burpressure (HTTP 429)**

- **Програма для виконання завдань, які запобігають аварійному завершенню роботи сервера під важким навантаженням:**Що тут відбувається?
- **Semaphore**: Як каскадер у клубі, тільки дозволяє N людям увійти одночасно (N =)
- **Менеджер контексту**): Автоматично стежити за вимірами і очистити
- **Кмітлива повторна спроба**: Повідомляє клієнтам "приходьте через 25 секунд" на основі глибини черги і середньої кількості запитів`Retry-After`Експоненціальний рух середньостатистичний

---


**: Згладжує шипи у час запиту**

- **Чому це важливо**: Під важким навантаженням повертає HTTP 429 замість аварійного аварійного завершення або нескінченної черги
- **4.**Магія маскування символів
- **Зберігати спеціальні символи (емоджіс, символи), які можуть зіпсувати моделі перекладу:**Використання прикладу:
- **Що тут відбувається?**Шаблон формального виразу
- **: Порівнює emoji і особливого символу діапазону Unicode**Система заповнювача
- **: Поміняти місцями**на

тимчасово

## Чому це важливо

: Моделі перекладу деколи руйнують або усувають емоджі - це зберігає їх у досконалому стані!

### 5.

```bash
# Prefer GPU if available (default)
USE_GPU=auto

# Force GPU
USE_GPU=true

# Force CPU
USE_GPU=false

# Explicit device override
DEVICE=cuda:0
DEVICE=cpu
```

### Інтелектуальна текстова розшифровка

```bash
# Model family selection (NEW in v2.0!)
MODEL_FAMILY=opus-mt   # Best quality (default)
MODEL_FAMILY=mbart50   # 50 languages, single model
MODEL_FAMILY=m2m100    # 100 languages, maximum coverage

# Auto-fallback between model families (NEW in v2.0!)
AUTO_MODEL_FALLBACK=1  # Enabled by default
MODEL_FALLBACK_ORDER="opus-mt,mbart50,m2m100"  # Priority order

# Volume-mapped model cache (NEW in v2.0!)
MODEL_CACHE_DIR=/models  # Persistent cache directory

# Model arguments passed to transformers.pipeline
EASYNMT_MODEL_ARGS='{"torch_dtype":"fp16"}'
EASYNMT_MODEL_ARGS='{"torch_dtype":"bf16","cache_dir":"/models"}'

# Preload models at startup (reduces first-request latency)
PRELOAD_MODELS="en->de,de->en,fr->en"

# LRU cache capacity
MAX_CACHED_MODELS=6
```

**Розбиває довгі тексти на шматки, які відповідають моделяційним обмеженням під час збереження меж речень:**

- **Що тут відбувається?**Розбиття речень
  
  - `opus-mt`: Застосовує regex для поділу на
  - `mbart50`під час збереження пунктуації
  - `m2m100`Жадібний кусень

- **: пакує якомога більше речень до кожного шматка без перевищення обмеження**Поділ на межі слова
  
  - `1`: Якщо одне речення задовге, розбиття на пробіли замість скорочення середнього слова
  - `0`Чому це важливо

- **: Моделі перекладу мають вхідні обмеження (зазвичай, 512- 1024 маркерів).**Це гарантує, що ми ніколи не перевищимо їх, зберігаючи контекст непошкодженим.
  
  - 6.`"opus-mt,mbart50,m2m100"`Асинхронне відкриття моделі з кешуванням
  - Динамічне виявлення доступних моделей перекладу за допомогою Hraging Face:`"m2m100,mbart50,opus-mt"`Що тут відбувається?

- **Асинхронний клієнт HTTP**): Робить неблоковані запити HTTP до обрізування лисиці
  
  - Кечування, засноване на часі`/models`: зберігає результати протягом однієї години, щоб уникнути обмеження швидкості`-v ./model-cache:/models`
  - Обробка назв моделей
  - : Видобування

**і**

- `fp16`від
- `bf16`Чому це важливо
- `fp32`: У Hacking Face є 1200+ Моделі Operus-MT.

### Обыскать их все займет 10 секунд.

```bash
# Batch size for translation (higher = faster but more VRAM)
EASYNMT_BATCH_SIZE=16  # CPU: 8-16, GPU: 32-64

# Maximum text length per item
EASYNMT_MAX_TEXT_LEN=1000

# Maximum beam size (higher = better quality but slower)
EASYNMT_MAX_BEAM_SIZE=5

# Worker thread pools
MAX_WORKERS_BACKEND=1    # Translation workers
MAX_WORKERS_FRONTEND=2   # Language detection workers
```

### Качування робить це миттєво!

```bash
# Enable request queueing (highly recommended)
ENABLE_QUEUE=1

# Max concurrent translations
# Auto: 1 on GPU, MAX_WORKERS_BACKEND on CPU
MAX_INFLIGHT_TRANSLATIONS=1

# Max queued requests before 429
MAX_QUEUE_SIZE=1000

# Per-request timeout (0 = disabled)
TRANSLATE_TIMEOUT_SEC=180

# Retry-After estimation
RETRY_AFTER_MIN_SEC=1      # Floor
RETRY_AFTER_MAX_SEC=120    # Ceiling
RETRY_AFTER_ALPHA=0.2      # EMA smoothing factor
```

### 7.

```bash
# Enable input filtering
INPUT_SANITIZE=1

# Minimum alphanumeric ratio (0.2 = 20%)
INPUT_MIN_ALNUM_RATIO=0.2

# Minimum character count
INPUT_MIN_CHARS=1

# Language code for undetermined/noise
UNDETERMINED_LANG_CODE=und
```

### Автоматичне визначення пристрою

```bash
# Default sentence splitting behavior
PERFORM_SENTENCE_SPLITTING_DEFAULT=1

# Max chars per sentence before word-boundary split
MAX_SENTENCE_CHARS=500

# Max chars per chunk for batching
MAX_CHUNK_CHARS=900

# Sentence joiner
JOIN_SENTENCES_WITH=" "
```

### Автоматично виявляти і використовувати GPU, якщо це можливо:

```bash
# Enable symbol masking
SYMBOL_MASKING=1

# What to mask
MASK_DIGITS=1    # Mask 0-9
MASK_PUNCT=1     # Mask .,!? etc.
MASK_EMOJI=1     # Mask 😀🎉 etc.
```

### Що тут відбувається?

```bash
# Align response array length to input
ALIGN_RESPONSES=1

# Placeholder for failed items (when aligned)
SANITIZE_PLACEHOLDER=""

# Response format
EASYNMT_RESPONSE_MODE=strings    # ["translation1", "translation2"]
EASYNMT_RESPONSE_MODE=objects    # [{"text":"translation1"}, ...]
```

### Визначення GPU

```bash
# Enable two-hop translation via pivot
PIVOT_FALLBACK=1

# Pivot language (usually English)
PIVOT_LANG=en
```

### : Використовуйте PyTorch для перевірки наявності CUDA

```bash
# Log level
LOG_LEVEL=INFO

# Per-request logging (verbose)
REQUEST_LOG=1

# Format
LOG_FORMAT=plain    # Human-readable
LOG_FORMAT=json     # Structured JSON

# File logging with rotation
LOG_TO_FILE=1
LOG_FILE_PATH=/var/log/marian-translator/app.log
LOG_FILE_MAX_BYTES=10485760    # 10MB
LOG_FILE_BACKUP_COUNT=5

# Include raw text in logs (privacy risk!)
LOG_INCLUDE_TEXT=0
```

### Автоматичне налаштування

```bash
# Periodically clear CUDA cache (seconds, 0=disabled)
CUDA_CACHE_CLEAR_INTERVAL_SEC=0
```

### : Набори

```bash
# Worker count (use 1 for single GPU)
WEB_CONCURRENCY=1

# Request timeout
TIMEOUT=60

# Graceful shutdown timeout
GRACEFUL_TIMEOUT=20

# Keep-alive timeout
KEEP_ALIVE=5
```

## на GPU (обмежена фрагментація VRAM) проти

### на процесорі (максичний паралелізм)

```bash
# GET request
curl "http://localhost:8000/translate?target_lang=de&text=Hello%20world&source_lang=en"

# Response
{
  "translations": ["Hallo Welt"]
}
```

### Вибір пристрою

```bash
# POST request
curl -X POST http://localhost:8000/translate \
  -H 'Content-Type: application/json' \
  -d '{
    "text": [
      "Hello world",
      "This is a test",
      "Machine translation is amazing"
    ],
    "target_lang": "de",
    "source_lang": "en",
    "beam_size": 1,
    "perform_sentence_splitting": true
  }'

# Response
{
  "target_lang": "de",
  "source_lang": "en",
  "translated": [
    "Hallo Welt",
    "Das ist ein Test",
    "Maschinenübersetzung ist erstaunlich"
  ],
  "translation_time": 0.342
}
```

### : Може бути специфічна GPU за допомогою

```bash
# Omit source_lang for auto-detection
curl -X POST http://localhost:8000/translate \
  -H 'Content-Type: application/json' \
  -d '{
    "text": ["Bonjour le monde"],
    "target_lang": "en"
  }'

# Response
{
  "target_lang": "en",
  "source_lang": "fr",  # Detected
  "translated": ["Hello world"],
  "translation_time": 0.156
}
```

### Журналювання

```bash
# GET
curl "http://localhost:8000/language_detection?text=Hola%20mundo"
# {"language": "es"}

# POST with batch
curl -X POST http://localhost:8000/language_detection \
  -H 'Content-Type: application/json' \
  -d '{"text": ["Hello", "Bonjour", "Hola"]}'
# {"languages": ["en", "fr", "es"]}
```

### : Показує назву GPU і VRAM під час запуску для зневаджування

```bash
# Health check
curl http://localhost:8000/healthz
# {"status": "ok"}

# Readiness
curl http://localhost:8000/readyz
# {
#   "status": "ready",
#   "device": "cuda:0",
#   "queue_enabled": true,
#   "max_inflight": 1
# }

# Cache status
curl http://localhost:8000/cache
# {
#   "capacity": 6,
#   "size": 3,
#   "keys": ["en->de", "de->en", "fr->en"],
#   "device": "cuda:0",
#   "inflight": 1,
#   "queue_enabled": true
# }

# Model info
curl http://localhost:8000/model_name | jq
```

### Шаблон Sington

```bash
# When queue is full, you get 429
curl -X POST http://localhost:8000/translate \
  -H 'Content-Type: application/json' \
  -d '{"text": ["test"], "target_lang": "de"}'

# Response: 429 Too Many Requests
# Headers: Retry-After: 45
# Body:
{
  "message": "Too many requests; queue full",
  "retry_after_sec": 45
}

# Proper client behavior:
# 1. Read Retry-After header
# 2. Wait that long + jitter
# 3. Retry request
```

## : Один приклад, що був поділений на всю програму

8.

### Експонентне рухоме середнє для повторень після

Плавна повторна оцінка, яка пристосовується до поточної тривалості запиту:

**Приклад:**

```powershell
.\build-all.ps1
```

**Що тут відбувається?**

```bash
chmod +x build-all.sh
./build-all.sh
```

### EMA (Expential рухове середнє)

: Подібно до середньої ваги, яка надає більшої ваги недавнім цінностям.**Коефіцієнт згладжування (⇩)**:

1. **: Керує тим, як швидко ми пристосовуємося до змін** (`latest`, `min`, `gpu`, `gpu-min`Чому це не є тільки середньостатистичний?
2. **: EMA швидше адаптується до змін під час фільтрування шипів**Чому це важливо`20250108.143022`: Надає клієнтам реалістичну інформацію

час, який слід застосувати до поточного навантаження на систему

```bash
# Always get the latest version
docker pull scottgal/mostlylucid-nmt:cpu
# Or use the :latest alias
docker pull scottgal/mostlylucid-nmt:latest

# Pin to a specific version for reproducibility
docker pull scottgal/mostlylucid-nmt:cpu-20250108.143022
docker pull scottgal/mostlylucid-nmt:cpu-min-20250108.143022
```

### Ці шаблони коду демонструють методи виробництва Python:

Керування виконавцями

- **: Явне очищення пам' яті GPU**Милосердна деградація
- **: Автоматичне повернення між постачальниками моделей**Робота з компенсацією
- **: Черга + HTTP 429 замість аварійного завершення**Цілісність даних
- **: Маскування символів зберігає спеціальні символи**Оптимізація швидкодії

: Кмітливий кеш, кусочок і паралельна обробка

```bash
docker inspect scottgal/mostlylucid-nmt:cpu | jq '.[0].Config.Labels'
```

Спостереження[: Детальне стеження за лісозаготівлею і вимірами](https://github.com/scottgal/mostlylucid-nmt/blob/main/BUILD.md).

## Кожна з цих можливостей вирішує справжню проблему виробництва, яка могла б спричинити катастрофи, помилки або поганий досвід користувача без них!

### Довідник з налаштування

```bash
# Using pre-built image from Docker Hub (recommended)
docker run -d \
  --name translator \
  -p 8000:8000 \
  -e ENABLE_QUEUE=1 \
  -e MAX_QUEUE_SIZE=500 \
  -e EASYNMT_BATCH_SIZE=16 \
  -e TIMEOUT=180 \
  -e LOG_LEVEL=INFO \
  -e REQUEST_LOG=0 \
  scottgal/mostlylucid-nmt

# Or build locally
docker build -t mostlylucid-nmt .
docker run -d --name translator -p 8000:8000 mostlylucid-nmt

# Check logs
docker logs -f translator
```

### Службу можна налаштувати за допомогою змінних середовища.

```bash
# Using pre-built GPU image from Docker Hub (recommended)
docker run -d \
  --name translator-gpu \
  --gpus all \
  -p 8000:8000 \
  -e USE_GPU=true \
  -e DEVICE=cuda:0 \
  -e PRELOAD_MODELS="en->de,de->en,en->fr,fr->en,en->es,es->en" \
  -e EASYNMT_MODEL_ARGS='{"torch_dtype":"fp16"}' \
  -e EASYNMT_BATCH_SIZE=64 \
  -e MAX_CACHED_MODELS=8 \
  -e ENABLE_QUEUE=1 \
  -e MAX_QUEUE_SIZE=2000 \
  -e WEB_CONCURRENCY=1 \
  -e TIMEOUT=180 \
  -e GRACEFUL_TIMEOUT=30 \
  -e LOG_FORMAT=json \
  -e LOG_TO_FILE=1 \
  -v /var/log/translator:/var/log/marian-translator \
  scottgal/mostlylucid-nmt:gpu

# Or build locally
docker build -f Dockerfile.gpu -t mostlylucid-nmt:gpu .
docker run -d --name translator-gpu --gpus all -p 8000:8000 mostlylucid-nmt:gpu

# Monitor cache and performance
watch -n 5 "curl -s http://localhost:8000/cache | jq"
```

### Ось повний провідник:

```yaml
version: '3.8'

services:
  translator:
    image: scottgal/mostlylucid-nmt:gpu  # Use pre-built image
    container_name: translator
    restart: unless-stopped

    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

    ports:
      - "8000:8000"

    environment:
      USE_GPU: "true"
      DEVICE: "cuda:0"
      PRELOAD_MODELS: "en->de,de->en,en->fr,fr->en"
      EASYNMT_MODEL_ARGS: '{"torch_dtype":"fp16"}'
      EASYNMT_BATCH_SIZE: "64"
      MAX_CACHED_MODELS: "8"
      ENABLE_QUEUE: "1"
      MAX_QUEUE_SIZE: "2000"
      WEB_CONCURRENCY: "1"
      TIMEOUT: "180"
      LOG_FORMAT: "json"
      LOG_TO_FILE: "1"

    volumes:
      - translator-logs:/var/log/marian-translator
      - translator-cache:/root/.cache/huggingface

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  translator-logs:
  translator-cache:
```

### Вибір пристрою

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: translator
spec:
  replicas: 2  # Scale horizontally for CPU, use 1 per GPU
  selector:
    matchLabels:
      app: translator
  template:
    metadata:
      labels:
        app: translator
    spec:
      containers:
      - name: translator
        image: scottgal/mostlylucid-nmt:gpu
        ports:
        - containerPort: 8000
        env:
        - name: USE_GPU
          value: "true"
        - name: EASYNMT_MODEL_ARGS
          value: '{"torch_dtype":"fp16"}'
        - name: PRELOAD_MODELS
          value: "en->de,de->en"
        - name: ENABLE_QUEUE
          value: "1"
        - name: MAX_QUEUE_SIZE
          value: "2000"

        resources:
          requests:
            memory: "4Gi"
            cpu: "2"
            nvidia.com/gpu: 1
          limits:
            memory: "8Gi"
            cpu: "4"
            nvidia.com/gpu: 1

        livenessProbe:
          httpGet:
            path: /healthz
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10

        readinessProbe:
          httpGet:
            path: /readyz
            port: 8000
          initialDelaySeconds: 20
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: translator
spec:
  selector:
    app: translator
  ports:
  - port: 80
    targetPort: 8000
  type: LoadBalancer
```

## Налаштування моделі

### Пояснення нових налаштувань:

1. **MODEL_ FAMILY**
   
   ```bash
   EASYNMT_MODEL_ARGS='{"torch_dtype":"fp16"}'
   ```
   
   - : Виберіть модель сім'ї, яку слід використовувати як основну
   - : Найкраща якість, 1200+параметрів, окремі моделі
   - : хороша якість, 50 мовами, єдина модель 2.4GB

2. **: хороша якість, 100 мов, єдина модель 2.2 ГБ**
   
   ```bash
   # Start high, reduce if you get OOM
   EASYNMT_BATCH_SIZE=64  # Try 128 on large GPUs
   ```

3. **AUTO_ MODEL_ FALLBACK**
   
   ```bash
   PRELOAD_MODELS="en->de,de->en,en->fr,fr->en,en->es,es->en"
   ```

4. **: Автоматично випробовувати інші сім' ї, якщо пара недоступна**
   
   ```bash
   WEB_CONCURRENCY=1
   MAX_INFLIGHT_TRANSLATIONS=1
   ```

5. **(типовий): увімкнено - максимальна обкладинка**
   
   ```bash
   MAX_CACHED_MODELS=10  # Keep more models in VRAM
   ```

6. **: Непрацездатний - строгий режим однієї сім'ї**
   
   ```bash
   # beam_size=1 is 3-5x faster than beam_size=5
   # Quality difference is often minimal
   curl -X POST ... -d '{"beam_size": 1, ...}'
   ```

### MODEL_ FALLBACK_ ORDER

1. **: Порядок пріоритету для повернення назад**
   
   ```bash
   EASYNMT_BATCH_SIZE=8
   ```

2. **Типове значення:**
   
   ```bash
   MAX_WORKERS_BACKEND=4
   MAX_INFLIGHT_TRANSLATIONS=4
   WEB_CONCURRENCY=2
   ```

3. **(перший якість)**
   
   ```bash
   PERFORM_SENTENCE_SPLITTING_DEFAULT=0
   ```

### Альтернативний:

1. **(перший захист)**
   
   ```javascript
   // Bad: 100 separate requests
   for (const text of texts) {
     await translate(text);
   }
   
   // Good: 1 batch request
   await translate(texts);
   ```

2. **MODEL_ CCHE_ DIR**
   
   ```javascript
   async function translateWithRetry(texts) {
     try {
       return await translate(texts);
     } catch (err) {
       if (err.status === 429) {
         const retryAfter = err.headers['retry-after'];
         const jitter = Math.random() * 5;
         await sleep((retryAfter + jitter) * 1000);
         return translateWithRetry(texts);
       }
       throw err;
     }
   }
   ```

3. **: Постійне взірцеве сховище на основі томів докерів.**
   
   ```javascript
   // Reuse HTTP connections
   const agent = new https.Agent({ keepAlive: true });
   ```

4. **Встановити до**
   
   ```javascript
   // Bad: mixed language pairs in one request
   translate([
     { text: "Hello", sourceLang: "en", targetLang: "de" },
     { text: "Bonjour", sourceLang: "fr", targetLang: "de" }
   ]);
   
   // Good: group by language pair
   translateBatch(enToDe, "en", "de");
   translateBatch(frToDe, "fr", "de");
   ```

## і об' єм карти:

### Модели, що продовжуються через перезапуск контейнера

1. **Спільний кеш між декількома контейнерами**параметри flash_ dtype:
2. **(float16): 2x швидше на GPU, половина пам'яті, незначна втрата якості**(bfloat16): Краща числова стабільність за fp16, потребує сучасні GPU
3. **(float32): Повна точність, найповільніша, але найточніша**Параметри перекладів
4. **& Швидкодія у черзі**Засновування вхідних даних
5. **Обробка речення**Маскування символів
6. **Поведінка відповіді**Повернення Pivot
7. **Журналювання**Супровід

### Gunicorn (Docker)

Приклади використання

```python
translation_requests_total{lang_pair="en->de",status="success"} 1523
translation_requests_total{lang_pair="en->de",status="error"} 7
translation_duration_seconds{lang_pair="en->de",quantile="0.5"} 0.342
translation_duration_seconds{lang_pair="en->de",quantile="0.95"} 1.234
translation_queue_depth 23
translation_cache_size 6
translation_cache_hits_total 8234
translation_cache_misses_total 142
```

### Основний переклад

```bash
# Enable JSON logging
LOG_FORMAT=json REQUEST_LOG=1

# Output example
{
  "ts": "2025-01-08T15:30:45+0000",
  "level": "INFO",
  "name": "app",
  "message": "translate_post done items=5 dt=0.342s",
  "req_id": "a3d2f5b1-c4e6-4f7a-9d8c-1e2f3a4b5c6d",
  "endpoint": "/translate",
  "src": "en",
  "tgt": "de",
  "items": 5,
  "duration_ms": 342
}
```

Пакетний переклад (рекомендовано)

## Автовиявлення мови

Лише виявлення мови
|---------|---------|-----------------|
| **Точка завершення спостереження**Як справлятися з придушенням
| **Будівництво і переклад**Тепер у всіх зображеннях Docker міститься відповідна версія і метадані для стеження.
| **Швидке збирання**Зібрати всі 4 варіанти з автоматичною версією дати:
| **Вікна:**Linux/Mac:
| **Стратегія перекладу**Створення кожної збірки
| **два мітки**Мітка з назвою
| **) - завжди вказує на останні**Мітка версії
| **(e.g.,**) - незмінний знімок
| **Приклади:**Мітки OCI
| **Кожне зображення містить метадані:**Версія
| **: Часовий штамп збирання (РРРРМРРД. ГГМСС)**Дата збирання
| **: ISO 8601 Часовий штамп**Git- внески

## : Коротка SHA

### Варіант

**: cpu- full, cpu- min, gpu- full або gpu- min**Перевірка міток:

**Докладніші настанови щодо збирання і інтеграції CI/CD можна знайти у розділі**

- BUILD. md`MAX_QUEUE_SIZE`
- Впровадження
- Впровадження процесора`MAX_INFLIGHT_TRANSLATIONS`Впровадження GPU
- Докер Композитний

### Взаємозв'язок Kubernetes

**Оптимізація швидкодії**Список перевірок Оптимізації GPU

**Використовувати точність FP16**

- 2x швидких підрахунків`ENABLE_QUEUE=1`
- Половина використання VRAM

### Нелегальна втрата якості для перекладу

**Пакетний розмір**Заздалегідь завантажувати гарячі моделі

**Один працівник на GPU**

- Збільшити розмір кешу`EASYNMT_BATCH_SIZE`
- Нижній розмір променя для протоки`MAX_CACHED_MODELS`
- Оптимізація ЦП`EASYNMT_MODEL_ARGS='{"torch_dtype":"fp16"}'`
- Нижній розмір пакета`WEB_CONCURRENCY=1`Збільшує паралелізм`MAX_INFLIGHT_TRANSLATIONS=1`

### Вимкнути розбиття речень для коротких текстів

**Найкращі вправи клієнта**Пакетні запити

**Повага до повторних спроб**

```bash
PRELOAD_MODELS="en->de,de->en"
```

### Використовувати набір з' єднань

**Група за парою мов** `Helsinki-NLP/opus-mt-{src}-{tgt}`Спостереження за і спостереженням

**Метрика клавіш для стеження**

- Перекласти через сітківку`PIVOT_FALLBACK=1`(запити/ сек)
- Середня спізнення`curl http://localhost:8000/lang_pairs`

### (p50, p95, p99)

**Глибина черги**(поточний рахунок очікування)

**Частота влучання у кеш**

- (% від запитів до кешу)`MASK_EMOJI=0`Частота помилок`MASK_PUNCT=0`
- (5xx відповідей)`SYMBOL_MASKING=0`

## Програма GPU

(якщо можна застосувати)

```csharp
public class MostlyLucidNmtClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;

    public MostlyLucidNmtClient(HttpClient httpClient, string baseUrl)
    {
        _httpClient = httpClient;
        _baseUrl = baseUrl;
    }

    public async Task<TranslationResponse> TranslateAsync(
        List<string> texts,
        string targetLang,
        string sourceLang = "",
        int beamSize = 1,
        bool performSentenceSplitting = true,
        CancellationToken cancellationToken = default)
    {
        var request = new TranslationRequest
        {
            Text = texts,
            TargetLang = targetLang,
            SourceLang = sourceLang,
            BeamSize = beamSize,
            PerformSentenceSplitting = performSentenceSplitting
        };

        var response = await _httpClient.PostAsJsonAsync(
            $"{_baseUrl}/translate",
            request,
            cancellationToken);

        if (response.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
        {
            // Read Retry-After header
            var retryAfter = response.Headers.RetryAfter?.Delta?.TotalSeconds ?? 30;
            var jitter = Random.Shared.Next(0, 5);
            await Task.Delay(TimeSpan.FromSeconds(retryAfter + jitter), cancellationToken);

            // Retry
            return await TranslateAsync(texts, targetLang, sourceLang, beamSize,
                performSentenceSplitting, cancellationToken);
        }

        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<TranslationResponse>(cancellationToken);
    }
}

public class TranslationRequest
{
    [JsonPropertyName("text")]
    public List<string> Text { get; set; }

    [JsonPropertyName("target_lang")]
    public string TargetLang { get; set; }

    [JsonPropertyName("source_lang")]
    public string SourceLang { get; set; }

    [JsonPropertyName("beam_size")]
    public int BeamSize { get; set; }

    [JsonPropertyName("perform_sentence_splitting")]
    public bool PerformSentenceSplitting { get; set; }
}

public class TranslationResponse
{
    [JsonPropertyName("target_lang")]
    public string TargetLang { get; set; }

    [JsonPropertyName("source_lang")]
    public string SourceLang { get; set; }

    [JsonPropertyName("translated")]
    public List<string> Translated { get; set; }

    [JsonPropertyName("translation_time")]
    public double TranslationTime { get; set; }
}
```

Використання пам' яті

```csharp
services.AddHttpClient<MostlyLucidNmtClient>(client =>
{
    client.BaseAddress = new Uri("http://translator:8000");
    client.Timeout = TimeSpan.FromMinutes(3);
});
```

## (VRAM для GPU, RAM для процесора)

Приклад Метриці Prometheus**Якщо ви інтегруєте Prometheus (не вбудовано, але просто додати):**Приклад структурованого журналу

### Ви можете передавати цю інформацію до Elatisicalsearch, HavyWatch, або до будь - якого лісозаготівельного агресора.

**Порівняння: EasyNMT vs Mis Lucid- NMT**

- Ті-Мт- д'Івуар- НМТ*
- Стабільність
- Переваги. Часті помилки.

**Обробка вхідних даних**

- Має значення seoji/ symbens ® Roust saentifiation + charching}
- Пригнічення
- ♪ None, OOMs під завантаженням ♪ Semaphore + queue with reep- 

**Спостереження**

- Дівчата/Райка/Вашний кінцевий пункт, структура цілих дробів
- Підтримка GPU
- *
- Керування моделями

**, без cashine LRU cache with auto- evicce}**

- Робота з реченнями
-  ♪ Кмітливо}*
- Переклад Pivot
-  Ні - автоматичне повернення назад через англійську #
- Милосердне вимикання

### ♪ Ні ♪ Так, з'являється ♪

Налаштування**  40 + env vars для тонкої тиші**Сумісність API

### ♪ TYNMT кінцеві пункти} 100% сумісні + розширення ♪

- **Якість коду**Дзвінок, Моношка, няня, випробуваний
- **Вирішення проблем**429 забагато запитів
- **Причина:**Черга повна.
- **Вирішення:**Збільшити
- **Додати більше копій (горизонтальне масштабування)**Збільшити
- **(якщо у вас є універмаг)**Зменшити розмір пакетів від клієнтів
- **503 Служба недоступна**Причина:
- **Чергування вимкнене і всі слоти зайняті.**Вирішення:

### Увімкнути чергування:

```bash
# Maximum coverage with auto-fallback (recommended!)
docker run -d -p 8000:8000 \
  -v ./model-cache:/models \
  -e MODEL_CACHE_DIR=/models \
  -e AUTO_MODEL_FALLBACK=1 \
  -e MODEL_FALLBACK_ORDER="opus-mt,mbart50,m2m100" \
  scottgal/mostlylucid-nmt:cpu-min

# GPU with best quality
docker run -d --gpus all -p 8000:8000 \
  -e USE_GPU=true \
  -e MODEL_FAMILY=opus-mt \
  -e EASYNMT_MODEL_ARGS='{"torch_dtype":"fp16"}' \
  scottgal/mostlylucid-nmt:gpu

# Test it
curl -X POST http://localhost:8000/translate \
  -H 'Content-Type: application/json' \
  -d '{"text": ["Hello world"], "target_lang": "de"}'
```

### Підвищити обмеження inflight, якщо у вас є ресурси

OOM (Не пам' ять) на GPU

**Причина:**

Пакетний розмір занадто високий або забагато моделей збережено.

---


## Вирішення:

- [Зменшити](https://huggingface.co/Helsinki-NLP)
- [Зменшити](https://huggingface.co/docs/transformers)
- [Увімкнути FP16:](https://fastapi.tiangolo.com/)
- [Забезпечення](https://pytorch.org/docs/stable/notes/cuda.html)

## і

Повільне перше прохання[Причина:

## Модель не попередньо завантажено.

`Translation` `NMT` `Neural Machine Translation` `Python` `FastAPI` `Docker` `CUDA` `PyTorch` `Transformers` `Helsinki-NLP` `Production` `Microservices` `API`