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: "AI 引擎參考,涵蓋所有本機 ML 工具。去背、放大、OCR、人臉偵測、相片修復等。"
i18n_source_hash: 14728c1dcd05
i18n_provenance: machine
i18n_output_hash: 36207813ccb8
i18n_output_hash: 4e37d784676e
i18n_source_hash: aa9a56cdddc7
i18n_provenance: human
---
# AI 引擎參考 {#ai-engine-reference}
`@snapotter/ai` 套件將 Node.js 橋接到一個**常駐的 Python sidecar**,用於所有 ML 操作。dispatcher 程序在兩次請求之間保持存活,以獲得快速的暖啟動效能。啟動時會自動偵測 NVIDIA CUDA,可用時即加以使用;否則 AI 工具會在 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 GPU 的系統,避免 CUDA 和該工具的驅動程式耦合。
目前不支援透過 VA-API、Quick Sync 或 OpenCL 進行 Intel/AMD iGPU 的 AI 推論加速。除非有支援 CUDA 的 NVIDIA GPU 可用,否則將 `/dev/dri` 對映進容器並不會加速這些 Python sidecar 工具。
19 個 Python sidecar AI 工具,橫跨四種模態(image、audio、video、document),另有 2 個具備選用 AI 功能的工具。所有模型都在本機執行,初次下載模型後即不需要網際網路。
<!-- 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 @@ AI 模型是依共用相依堆疊來封裝,而非每個工具一個封存檔
Docker 映像隨附應用程式加上共用執行環境。大型模型封存檔會在需要時下載到常駐的 `/data/ai` 磁碟區,之後由所有需要它的工具重複使用。如果某個套件包已因另一個工具的需要而安裝,啟用一個新的相依工具並不會再次下載該套件包。
每個 AI 工具在能執行前都需要一個或多個功能套件包。管理 UI 是依工具透過 `POST /api/v1/admin/tools/:toolId/features/install` 進行安裝,它解析完整的套件包清單、略過已安裝的套件包,並只將缺少的下載排入佇列。舉例來說,在全新的執行個體上啟用 Passport Photo 會將 `background-removal` `face-detection` 排入佇列;若在 Background Removal 已安裝後才啟用它,則只會將 `face-detection` 排入佇列
大多數人工智慧工具都需要一個或多個功能包才能運作。 管理 UI 透過 `POST /api/v1/admin/tools/:toolId/features/install` 工具安裝這些包,它解析完整的捆綁包列表,跳過已安裝的捆綁包,並僅對缺少的下載進行排隊。 例如,在新實例佇列 `background-removal` `face-detection` 上啟用 Passport Photo; 在已安裝背景刪除後啟用它僅排隊 `face-detection`。 OCR 是例外,因為 `fast` 不需要包裝; 透過 UI 或 `POST /api/v1/admin/features/ocr/install` 安裝其選購的精確執行時間
| 套件包 | 大小 | 共用相依群組 | 使用它的工具 |
|--------|------|-------------------------|-------------------|
@@ -61,7 +71,7 @@ Docker 映像隨附應用程式加上共用執行環境。大型模型封存檔
| `object-eraser-colorize` | 1-2 GB | LaMa 影像修補/外延與 DDColor | erase-object、colorize、ai-canvas-expand |
| `upscale-enhance` | 5-6 GB | RealESRGAN、GFPGAN / CodeFormer、去雜訊 | upscale、enhance-faces、noise-removal |
| `photo-restoration` | 4-5 GB | 刮痕修復與修復流程 | restore-photo |
| `ocr` | 5-6 GB | PaddleOCR / Tesseract OCR 堆疊 | 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 MB | faster-whisper 語音轉文字模型 | transcribe-audio、auto-subtitles |
具有跨套件包相依性的工具:
@@ -71,7 +81,17 @@ Docker 映像隨附應用程式加上共用執行環境。大型模型封存檔
| `passport-photo` | `background-removal``face-detection` | 先移除背景,再用人臉特徵點依護照與身分證照片規則框住裁切範圍。 |
| `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。 兩個版本都透過 ONNX Runtime 的 `CPUExecutionProvider` 運行 RapidOCR, 因此,相同的套件適用於僅 CPU 和 NVIDIA Docker 主機。 準確的運行時需要至少 4 GiB 的有效記憶體:配置的容器 cgroup 限制,否則為主機記憶體。 低於該簽章相容性最低值的系統在下載前會被拒絕。 此要求不適用於內建 Fast OCR。 Bare-metal 建置被拒絕,因為它們的 libc 和 Python ABI 無法安全推斷; 當主機提供 Tesseract 和 Ghostscript 時,快速 OCR 保持可用。
選用工件大約壓縮 208-234 MiB 並提取 409-488 MiB,具體取決於架構。 簽章索引綁定安裝程式強制執行的精確壓縮和提取位元組計數。 內建 Tesseract 在官方鏡像上增加了約25個 MiB,並且不需要`/data/ai`中的檔案。
線上安裝會取得已簽署的版本索引以及目前平台的精確內容尋址工件。 SnapOtter 在原子啟動新世代之前驗證 Ed25519 索引簽章、工件大小、SHA-256 摘要、模型摘要、路徑、檔案模式和暫存 smoke test。 失敗的安裝會使先前的健康生成保持活動狀態。
對於氣隙安裝,請使用名為 `index``archive` 的多部分欄位將版本的 `ocr-runtime-index.json` 和相符的 OCR 執行時間存檔上傳到 `POST /api/v1/admin/features/import`。 離線導入應用與線上安裝相同的簽名、哈希、提取、相容性和冒煙測試檢查; 沒有可信任簽名索引的檔案將被拒絕。
---
@@ -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` | 布林值 | 取決於層級 | 提高局部對比。快速直接應用;僅當校準得分提高 OCR 時,準確的等級才會保留變體。預設為“最佳” |
| `engine` | 細繩 | - | 已棄用的兼容性別名。將 `tesseract`應到 `fast`,並將舊版 `paddleocr` 值對應到 `balanced`;它不載入 PaddlePaddle |
傳回結構化結果,包含邊界框、信賴分數與擷取的文字區塊
傳回提取的文字以及來源元資料:引擎、請求的和實際的品質、設備、提供者、降級狀態、警告和準確的運行時/模型版本(如果適用)。 明確的品質要求永遠不會退回到另一層。 如果 `balanced``best` 不可用,則 API 傳回 `FEATURE_NOT_INSTALLED``FEATURE_INCOMPATIBLE`,而不是靜默執行 `fast`
## PDF OCR {#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` | 布林值 | 取決於層級 | 提高局部對比。快速直接應用;僅當校準得分提高 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: 9fa4a9a91996
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` | 移除背景 | rembgBiRefNet / 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 功能 bundle(在 Docker 環境中安裝/解除安裝 AI 模型套件)。從自訂自動化流程啟用工具時,建議使用工具層級的安裝端點:某些 AI 工具需要一個以上的共用 bundle,而此端點會略過已安裝的 bundle,只將缺少的排入佇列。
OCR 是可選增強功能而不是硬依賴項。 其 `fast` Tesseract 層無需包裝即可運作; `POST /api/v1/admin/features/ocr/install` 安裝簽名的 RapidOCR 打包 `balanced``best` 在 Linux amd64 或者 arm64。 準確的 OCR 運行時在僅 CPU 和 NVIDIA 主機上使用 CPU,並且需要至少 4 GiB 的有效記憶體(配置的容器 cgroup 限制,否則主機記憶體)。 SnapOtter 報告 `requiredMemoryBytes``effectiveMemoryBytes``insufficient-memory` 相容性原因,並在下載前拒絕不相容的安裝。 此記憶體需求不適用於 `fast`。 該包大約需要下載 208-234 MiB 和安裝 409-488 MiB,具體取決於目標; 簽章索引綁定安裝期間強制執行的確切大小。
| Method | Path | 存取權限 | 說明 |
|--------|------|--------|-------------|
| `GET` | `/api/v1/features` | Auth | 列出所有功能 bundle 及其安裝狀態 |
@@ -601,7 +605,18 @@ data: {"jobId":"...","type":"batch","status":"processing","completedFiles":2,"to
| `POST` | `/api/v1/admin/tools/:toolId/features/install` | Admin`features:manage`) | 安裝某工具所需的每個 bundle;回傳各 bundle 的已排入佇列/已略過狀態 |
| `POST` | `/api/v1/admin/features/:bundleId/uninstall` | Admin`features:manage`) | 解除安裝功能 bundle 並清除模型檔案 |
| `GET` | `/api/v1/admin/features/disk-usage` | Admin`features:manage`) | 取得 AI 模型的總磁碟使用量 |
| `POST` | `/api/v1/admin/features/import` | Admin`features:manage` | 匯入離線 AI bundle 封存 |
| `POST` | `/api/v1/admin/features/import` | 管理員 (`features:manage`) | 匯入舊版 AI 套裝 (`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"
```
在 arm64 上使用 `linux-arm64-cpu-py311` 檔案。另一個目標的簽名工件被拒絕而不是安裝。
## 管理操作 {#admin-operations}