fix: make OCR portable and reliable across AMD64 and ARM64 (#519)

* fix: make OCR portable and reliable

* fix: harden OCR installation portability

* fix: pin OCR partials across downloads

* fix: make OCR execution reliably asynchronous

* fix: harden OCR portability and docs routes

* fix: preserve decoder and docs safeguards
This commit is contained in:
SnapOtter
2026-07-15 03:34:24 +08:00
committed by GitHub
parent 58121f205f
commit 991c981529
409 changed files with 67151 additions and 8076 deletions
+41 -17
View File
@@ -1,18 +1,26 @@
---
description: "Довідник рушія ШІ з усіма локальними інструментами ML. Видалення фону, збільшення роздільної здатності, OCR, розпізнавання облич, реставрація фото та інше."
i18n_source_hash: 14728c1dcd05
i18n_provenance: machine
i18n_output_hash: e36cdc2779d7
i18n_output_hash: 3a80b8a66b82
i18n_source_hash: aa9a56cdddc7
i18n_provenance: human
---
# Довідник рушія ШІ {#ai-engine-reference}
Пакет `@snapotter/ai` з'єднує Node.js із **постійним допоміжним процесом Python** для всіх операцій ML. Процес диспетчера залишається активним між запитами задля швидкого «теплого» старту. NVIDIA CUDA автоматично визначається під час запуску та використовується за наявності; в іншому разі інструменти ШІ працюють на CPU.
Пакет `@snapotter/ai` координує власні інструменти та середовище виконання Python для локальних операцій ML. Більшість інструментів ML використовують постійний Python sidecar для швидкого гарячого запуску. OCR навмисно відокремлений: `fast` викликає власний двійковий файл Tesseract, тоді як `balanced` і `best` використовують виділений постійний JSONL dispatcher, закріплений на активному незмінному поколінні RapidOCR під `/data/ai/v3`. Кожен запит містить generation lease. Під час оновлення SnapOtter запускає smoke test на кандидаті перед активацією, атомарно перемикається на новий dispatcher, а потім зливає старе покоління перед garbage collection.
NVIDIA CUDA автоматично визначається та використовується середовищами виконання, які його підтримують. OCR використовує CPU на кожному хості, включаючи системи з графічними процесорами NVIDIA, уникаючи CUDA і підключення драйверів для цього інструменту.
Прискорення на iGPU Intel/AMD через VA-API, Quick Sync або OpenCL наразі не підтримується для інференсу ШІ. Прокидання `/dev/dri` в контейнер не прискорює ці інструменти допоміжного процесу Python, якщо немає NVIDIA GPU з підтримкою CUDA.
19 інструментів ШІ на допоміжному процесі Python у чотирьох модальностях (зображення, аудіо, відео, документ), а також 2 інструменти з необов'язковими можливостями ШІ. Усі моделі працюють локально: після початкового завантаження моделі інтернет не потрібен.
<!-- korean-ocr-contract:start -->
::: info Сумісність OCR для корейської мови
Швидкий OCR підтримує `auto`, `en`, `de`, `es`, `fr`, `zh` і `ja`, але не корейську мову (`ko`). Для корейської потрібен пакет точного OCR і рівень `balanced` або `best`. Пакет працює в офіційних контейнерах Linux amd64 і arm64, зокрема на вузлах NVIDIA, де OCR і далі виконується на CPU. Непідтримувані системи отримують явну помилку сумісності без прихованого переходу на `fast`. Корейська з `fast` або застарілим псевдонімом `tesseract` відхиляється до постановки в чергу з `FEATURE_INCOMPATIBLE` і `fast-korean-unsupported`.
:::
<!-- korean-ocr-contract:end -->
## Архітектура {#architecture}
```
@@ -22,15 +30,17 @@ Node.js Tool Route
@snapotter/ai bridge.ts
| (stdin/stdout JSON + stderr progress events)
v
Python dispatcher (persistent process, "ai" profile)
+-- Native Tesseract + Ghostscript (fast image/PDF OCR)
|
+-- Isolated OCR runtime (persistent JSONL dispatcher)
| `-- RapidOCR + ONNX Runtime CPU + pinned PP-OCR models
|
`-- Python dispatcher (persistent process, "ai" profile)
|
|-- remove_bg.py (rembg / BiRefNet)
|-- upscale.py (RealESRGAN)
|-- inpaint.py (LaMa ONNX)
|-- outpaint.py (LaMa canvas expansion)
|-- ocr.py (PaddleOCR / Tesseract)
|-- ocr_pdf.py (page-by-page document OCR)
|-- ocr_preprocess.py (image enhancement for OCR)
|-- detect_faces.py (MediaPipe)
|-- face_landmarks.py (MediaPipe landmarks)
|-- enhance_faces.py (GFPGAN / CodeFormer)
@@ -52,7 +62,7 @@ Node.js Tool Route
Docker-образ постачає застосунок разом зі спільним середовищем виконання. Великі архіви моделей завантажуються за потреби в постійний том `/data/ai`, а далі повторно використовуються кожним інструментом, якому вони потрібні. Якщо набір уже встановлено, бо його потребував інший інструмент, увімкнення нового залежного інструмента не завантажує цей набір повторно.
Кожен інструмент ШІ вимагає одного чи кількох наборів функцій, перш ніж зможе працювати. Адмін-інтерфейс встановлює за інструментом через `POST /api/v1/admin/tools/:toolId/features/install`, який розкриває повний список наборів, пропускає вже встановлені набори та ставить у чергу лише відсутні завантаження. Наприклад, увімкнення Passport Photo на новому екземплярі ставить у чергу `background-removal` і `face-detection`; увімкнення його після того, як уже встановлено Background Removal, ставить у чергу лише `face-detection`.
Більшість інструментів штучного інтелекту потребують одного або кількох пакетів функцій, перш ніж вони зможуть працювати. Інтерфейс адміністратора встановлює ці інструменти за допомогою `POST /api/v1/admin/tools/:toolId/features/install`, який розкриває повний список пакетів, пропускає пакети, які вже встановлено, і ставить у чергу лише відсутні завантаження. Наприклад, увімкнення Passport Photo у нових чергах екземплярів `background-removal` і `face-detection`; увімкнення після того, як видалення фону вже встановлено, черги лише `face-detection`. OCR є винятком, оскільки `fast` не потребує пакета; інсталюйте необов’язкове точне середовище виконання через інтерфейс користувача або `POST /api/v1/admin/features/ocr/install`.
| Набір | Розмір | Група спільних залежностей | Інструменти, що його використовують |
|--------|------|-------------------------|-------------------|
@@ -61,7 +71,7 @@ Docker-образ постачає застосунок разом зі спіл
| `object-eraser-colorize` | 1-2 ГБ | inpainting/outpainting LaMa та DDColor | erase-object, colorize, ai-canvas-expand |
| `upscale-enhance` | 5-6 ГБ | RealESRGAN, GFPGAN / CodeFormer, шумозаглушення | upscale, enhance-faces, noise-removal |
| `photo-restoration` | 4-5 ГБ | конвеєр ремонту подряпин і реставрації | restore-photo |
| `ocr` | 5-6 ГБ | стек OCR PaddleOCR / Tesseract | ocr, ocr-pdf |
| `ocr` | ~208-234 MiB завантажити / ~409-488 MiB встановити | Додаткові RapidOCR 3.9.1, ONNX Runtime 1.20.1 і закріплені моделі PP-OCR | ocr, ocr-pdf (лише `balanced` і `best`) |
| `transcription` | ~600 МБ | моделі мовлення в текст faster-whisper | transcribe-audio, auto-subtitles |
Інструменти з міжнабірними залежностями:
@@ -71,7 +81,17 @@ Docker-образ постачає застосунок разом зі спіл
| `passport-photo` | `background-removal`, `face-detection` | Видаляє фон, а потім за орієнтирами обличчя кадрує кроп під правила фото на паспорт та ID. |
| `enhance-faces` | `upscale-enhance`, `face-detection` | Розпізнає обличчя перед запуском покращення GFPGAN або CodeFormer на вибраних областях облич. |
Інструмент доступний лише тоді, коли встановлено всі потрібні йому набори. Часткові встановлення є коректними та обробляються поетапно: встановлені набори повторно використовуються, відсутні набори показуються як завантаження, а поставлені в чергу встановлення виконуються по одному, щоб спільне середовище Python не змінювалося одночасно.
Інструмент доступний лише тоді, коли встановлено всі його необхідні пакети, окрім OCR: його вбудований рівень `fast` залишається доступним без додаткового пакета OCR. Часткові встановлення є дійсними та обробляються поступово: встановлені пакети використовуються повторно, відсутні пакети відображаються як завантаження, а встановлення в черзі виконуються по одному, тому спільне середовище Python не змінюється одночасно.
### Точна інсталяція під час виконання OCR {#accurate-ocr-runtime-installation}
Точний пакет OCR — це середовище виконання для конкретної платформи для офіційного контейнера Linux amd64 або Linux arm64. Збірка amd64 використовує Python 3.12; збірка arm64 використовує Python 3.11. Обидві збірки запускають RapidOCR через `CPUExecutionProvider` ONNX Runtime, тому той самий пакет працює лише на центральному процесорі та хостах NVIDIA Docker. Точний час виконання вимагає принаймні 4 GiB ефективної пам’яті: обмеження налаштованого контейнера cgroup, інакше пам’ять хоста. Система, яка не відповідає мінімальній сумісності зі знаком, відхиляється перед завантаженням. Ця вимога не стосується вбудованого Fast OCR. Збірки Bare-metal відхиляються, оскільки їхні libc і Python ABI не можуть бути безпечно визначені; Швидкий OCR залишається доступним, якщо хост надає Tesseract і Ghostscript.
Додатковий артефакт становить близько 208-234 MiB стиснутих і 409-488 MiB вилучених, залежно від архітектури. Підписаний індекс прив’язує точну кількість стиснутих і витягнутих байтів, встановлених програмою встановлення. Вбудований Tesseract додає близько 25 MiB до офіційного образу та не потребує файлів у `/data/ai`.
Онлайн-інсталяція отримує підписаний індекс випуску та точний артефакт із адресою вмісту для поточної платформи. SnapOtter перевіряє підпис індексу Ed25519, розмір артефакту, дайджест SHA-256, дайджести моделі, шляхи, режими файлів і поетапний smoke test перед атомарною активацією нового покоління. Невдала інсталяція залишає активним попереднє здорове покоління.
Для інсталяції без розриву завантажте як `ocr-runtime-index.json` випуску, так і відповідний архів середовища виконання OCR до `POST /api/v1/admin/features/import`, використовуючи багатокомпонентні поля з назвами `index` і `archive`. Офлайн-імпорт використовує ті самі перевірки підпису, хешу, вилучення, сумісності та димового тесту, що й онлайн-інсталяція; архів без довіреного підписаного індексу відхилено.
---
@@ -143,16 +163,16 @@ Docker-образ постачає застосунок разом зі спіл
## OCR / Витяг тексту {#ocr-text-extraction}
**Маршрут інструмента:** `ocr`
**Моделі:** Tesseract (швидко), PaddleOCR PP-OCRv5 (збалансовано), PaddleOCR-VL 1.5 (найкраще)
**Моделі:** Tesseract (`fast`); RapidOCR з маленькими моделями PP-OCRv6 (`balanced`); Середні моделі PP-OCRv6 з каліброваним варіантом балів (`best`)
| Параметр | Тип | За замовчуванням | Опис |
|-----------|------|---------|-------------|
| `quality` | `"fast"` \| `"balanced"` \| `"best"` | `"balanced"` | Рівень обробки |
| `quality` | `"fast"` \| `"balanced"` \| `"best"` | Динамічний | Якщо `quality` і `engine` не задано, SnapOtter вибирає найкращий доступний рівень у порядку `best`, `balanced`, `fast`. Для корейської мови `fast` ніколи не вибирається: використовується `best`, потім `balanced`, або повертається помилка встановлення чи сумісності точного середовища виконання. |
| `language` | string | `"auto"` | Мова: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` |
| `enhance` | boolean | `true` | Попередньо обробити зображення для підвищення точності OCR |
| `engine` | string | - | Застаріле. Зіставляє `tesseract` з `fast`, `paddleocr` з `balanced` |
| `enhance` | логічний | Залежно від рівня | Поліпшення локального контрасту. Fast застосовує його безпосередньо; точні рівні зберігають варіант лише тоді, коли калібрована оцінка покращує OCR. За замовчуванням для найкращого |
| `engine` | рядок | - | Застарілий псевдонім сумісності. Зіставляє `tesseract` на `fast` і застаріле значення `paddleocr` на `balanced`; він не завантажує PaddlePaddle |
Повертає структуровані результати з обмежувальними рамками, оцінками впевненості та витягнутими блоками тексту.
Повертає витягнутий текст, а також метадані про походження: механізм, запитану та фактичну якість, пристрій, постачальника, стан деградації, попередження та точні версії часу виконання/моделі, якщо це можливо. Явні запити щодо якості ніколи не повертаються до іншого рівня. Якщо `balanced` або `best` недоступні, API повертає `FEATURE_NOT_INSTALLED` або `FEATURE_INCOMPATIBLE` замість тихого запуску `fast`.
## OCR для PDF {#pdf-ocr}
@@ -163,9 +183,13 @@ Docker-образ постачає застосунок разом зі спіл
| Параметр | Тип | За замовчуванням | Опис |
|-----------|------|---------|-------------|
| `quality` | `"fast"` \| `"balanced"` \| `"best"` | `"balanced"` | Рівень обробки |
| `quality` | `"fast"` \| `"balanced"` \| `"best"` | Динамічний | Якщо `quality` і `engine` не задано, SnapOtter вибирає найкращий доступний рівень у порядку `best`, `balanced`, `fast`. Для корейської мови `fast` ніколи не вибирається: використовується `best`, потім `balanced`, або повертається помилка встановлення чи сумісності точного середовища виконання. |
| `language` | string | `"auto"` | Мова: `auto`, `en`, `de`, `fr`, `es`, `zh`, `ja`, `ko` |
| `pages` | string | `"all"` | Вибір сторінок: `"all"`, `"1-3"`, `"1,3,5"` |
| `enhance` | логічний | Залежно від рівня | Поліпшення локального контрасту. Fast застосовує його безпосередньо; точні рівні зберігають варіант лише тоді, коли калібрована оцінка покращує OCR. За замовчуванням для найкращого |
| `engine` | рядок | - | Застарілий псевдонім сумісності. Зіставляє `tesseract` на `fast` і застаріле значення `paddleocr` на `balanced`; він не завантажує PaddlePaddle |
Таке ж правило заборони на пониження версії застосовується до PDF OCR. Сторінки PDF растеризуються перед розпізнаванням, і один запит може вибрати не більше 50 сторінок.
## Розмиття облич / PII {#face-pii-blur}
+20 -5
View File
@@ -1,8 +1,8 @@
---
description: "Повний довідник REST API. Кінцеві точки інструментів, пакетна обробка, конвеєри, бібліотека файлів, автентифікація, команди й адміністративні операції."
i18n_source_hash: 8646977f7cc9
i18n_provenance: machine
i18n_output_hash: 20d37040e8ea
i18n_source_hash: b89b5df16af5
i18n_provenance: human
---
# Довідник REST API {#rest-api-reference}
@@ -178,7 +178,7 @@ curl -X POST http://localhost:1349/api/v1/tools/<section>/<toolId>/batch \
| `remove-background` | Видалення фону | rembg (BiRefNet / U2-Net) | `model`, `backgroundType` (transparent/color/gradient/blur/image), `backgroundColor`, `gradientColor1`, `gradientColor2`, `gradientAngle`, `blurEnabled`, `blurIntensity`, `shadowEnabled`, `shadowOpacity` |
| `upscale` | Масштабування зображення | RealESRGAN | `scale` (2/4), `model`, `faceEnhance`, `denoise`, `format`, `quality` |
| `erase-object` | Ластик об'єктів | LaMa (ONNX) | Маска надсилається як друга частина файлу (ім'я поля `mask`), `format`, `quality` |
| `ocr` | OCR / Витяг тексту | PaddleOCR / Tesseract | `quality` (fast/balanced/best), `language`, `enhance` |
| `ocr` | OCR / Вилучення тексту | Tesseract (швидкий); RapidOCR + PP-OCR ONNX (збалансований/найкращий) | `quality` (швидкий/збалансований/найкращий), `language`, `enhance` |
| `blur-faces` | Розмиття облич / PII | MediaPipe | `blurRadius`, `sensitivity` |
| `smart-crop` | Розумне обрізання | MediaPipe + Sharp | `mode` (subject/face/trim), `strategy` (attention/entropy), `width`, `height`, `padding`, `facePreset` (closeup/head-shoulders/upper-body/half-body), `sensitivity`, `threshold`, `padToSquare`, `padColor`, `targetSize`, `quality` |
| `image-enhancement` | Покращення зображення | На основі аналізу | `mode` (auto/exposure/contrast/color/sharpness), `strength` |
@@ -425,7 +425,9 @@ curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \
## Пакетна обробка {#batch-processing}
Застосуйте загальний пакетний інструмент до кількох файлів одночасно. Повертає ZIP-архів. Власні багатофайлові або багатокрокові маршрути, як-от підпис PDF, PDF OCR і маршрути пресетів PDF-у-зображення, використовують власний контракт кінцевої точки замість загального маршруту `/batch`.
Застосуйте загальний пакетний інструмент до кількох файлів одночасно. Повертає ZIP-архів. Власні багатофайлові або багатокрокові маршрути, як-от підпис PDF і маршрути пресетів PDF-у-зображення, використовують власний контракт кінцевої точки замість загального маршруту `/batch`.
Інструмент `ocr-pdf` підтримує цей загальний маршрут `/batch`.
```bash
curl -X POST http://localhost:1349/api/v1/tools/image/compress/batch \
@@ -594,6 +596,8 @@ data: {"jobId":"...","type":"batch","status":"processing","completedFiles":2,"to
Керування наборами AI-можливостей (встановлення/видалення пакетів AI-моделей у середовищі Docker). Віддавайте перевагу кінцевій точці встановлення на рівні інструмента, коли вмикаєте інструмент з власної автоматизації: деякі AI-інструменти потребують більш ніж одного спільного набору, а ця кінцева точка пропускає вже встановлені набори, ставлячи в чергу лише відсутні.
OCR — це додаткове розширення, а не жорстка залежність. Його рівень `fast` Tesseract працює без пакета; `POST /api/v1/admin/features/ocr/install` встановлює підписаний пакет RapidOCR для `balanced` і `best` на Linux amd64 або arm64. Точне середовище виконання OCR використовує CPU на хостах лише з процесором і NVIDIA і вимагає принаймні 4 GiB ефективної пам’яті (ліміт налаштованого контейнера cgroup, інакше пам’ять хосту). SnapOtter повідомляє `requiredMemoryBytes`, `effectiveMemoryBytes` і причину сумісності `insufficient-memory` і відхиляє несумісне встановлення перед завантаженням. Ця вимога до пам’яті не стосується `fast`. Пакет містить близько 208-234 MiB для завантаження та 409-488 MiB для встановлення, залежно від цілі; підписаний індекс прив’язує точні розміри, які застосовуються під час встановлення.
| Метод | Шлях | Доступ | Опис |
|--------|------|--------|-------------|
| `GET` | `/api/v1/features` | Автентиф. | Список усіх наборів можливостей та їхнього статусу встановлення |
@@ -601,7 +605,18 @@ data: {"jobId":"...","type":"batch","status":"processing","completedFiles":2,"to
| `POST` | `/api/v1/admin/tools/:toolId/features/install` | Адмін (`features:manage`) | Встановити кожен набір, потрібний інструменту; повертає статус queued/skipped для кожного набору |
| `POST` | `/api/v1/admin/features/:bundleId/uninstall` | Адмін (`features:manage`) | Видалити набір можливостей і очистити файли моделей |
| `GET` | `/api/v1/admin/features/disk-usage` | Адмін (`features:manage`) | Отримати загальне використання диска AI-моделями |
| `POST` | `/api/v1/admin/features/import` | Адмін (`features:manage`) | Імпортувати офлайн-архів AI-набору |
| `POST` | `/api/v1/admin/features/import` | Адміністратор (`features:manage`) | Імпортуйте застарілий пакет штучного інтелекту (`file`) або підписаний автономний випуск OCR (`index` плюс `archive`) |
Імпорт OCR із повітряним проміжком має містити підписаний `ocr-runtime-index.json` випуску та відповідний архів платформи. SnapOtter застосовує ті самі перевірки підпису Ed25519, хешу артефакту, сумісності, вилучення та димового тесту, які використовуються під час онлайн-інсталяції:
```bash
curl -X POST http://localhost:1349/api/v1/admin/features/import \
-H "Authorization: Bearer <admin-token>" \
-F "index=@ocr-runtime-index.json" \
-F "archive=@ocr-linux-amd64-cpu-py312.tar.gz"
```
Використовуйте архів `linux-arm64-cpu-py311` на arm64. Підписаний артефакт для іншої цілі відхиляється, а не встановлюється.
## Адміністративні операції {#admin-operations}