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
+6 -6
View File
@@ -1,8 +1,8 @@
---
description: "โครงสร้าง monorepo, สถาปัตยกรรมของแอปและแพ็กเกจ, วงจรชีวิตของคำขอ และรอยเท้าทรัพยากรของ SnapOtter"
i18n_source_hash: 9e8f80499a37
i18n_provenance: human
i18n_output_hash: d1d73eea741b
i18n_source_hash: 733cb3c10884
i18n_provenance: human
---
# Architecture {#architecture}
@@ -36,13 +36,13 @@ snapotter/
### `@snapotter/ai` {#snapotter-ai}
เลเยอร์เชื่อมต่อที่เรียกสคริปต์ Python สำหรับการดำเนินการ ML เื่อใช้งานครั้งแรก บริดจ์จะเริ่มกระบวนการ Python dispatcher ที่คงอยู่ ซึ่งนำเข้าไลบรารีหนัก (PIL, NumPy, MediaPipe, rembg) ไว้ล่วงหน้า เพื่อให้การเรียก AI ครั้งต่อไปข้ามค่าใช้จ่ายการนำเข้า หาก dispatcher ยังไม่พร้อม บริดจ์จะย้อนกลับไปสร้าง subprocess ของ Python ใหม่ต่อคำขอ
เลเยอร์บริดจ์ที่เรียกเนทีฟและรันไทม์ Python ML เครื่องมือ Python ส่วนใหญ่ใช้ dispatcher แบบถาวรที่นำเข้าไลบรารีขนาดใหญ่ล่วงหน้า (PIL, NumPy, MediaPipe, rembg) ดังนั้นการโทรครั้งต่อไปจะข้ามค่าใช้จ่ายในการนำเข้า OCR ถูกแยกออกจากสภาพแวดล้อมที่ใช้ร่วมกันที่ไม่แน่นอน: `fast` เรียกใช้ Tesseract ดั้งเดิม ในขณะที่ `balanced` และ `best` ใช้ JSONL dispatcher ถาวรโดยเฉพาะที่ปักหมุดไว้กับรุ่น RapidOCR/ONNX ที่ไม่เปลี่ยนรูปแบบที่ใช้งานอยู่ แต่ละคำขอจะมี generation lease การเปิดใช้งานจะรัน smoke test บนตัวเลือกแรก จากนั้นจึงสลับไปที่ dispatcher แบบอะตอมมิก dispatcher รุ่นก่อนหน้าจะระบายออกก่อนที่จะมีการรวบรวมขยะ
**โมเดลไม่ได้ถูกโหลดล่วงหน้า** สคริปต์ของแต่ละเครื่องมือโหลดน้ำหนักโมเดลจากดิสก์ ณ เวลาที่ขอ และทิ้งเมื่อคำขอเสร็จสิ้น ดู [Resource footprint](#resource-footprint) สำหรับโปรไฟล์หน่วยความจำทั้งหมด
การดำเนินการที่รองรับ: การลบพื้นหลัง (rembg/BiRefNet), การขยายภาพ (RealESRGAN), การเบลอใบหน้า (MediaPipe), การเพิ่มความคมชัดใบหน้า (GFPGAN/CodeFormer), การลบวัตถุ (LaMa ONNX), OCR (PaddleOCR/Tesseract), การลงสี (DDColor), การลบสัญญาณรบกวน, การลบตาแดง, การฟื้นฟูภาพถ่าย, การสร้างรูปถ่ายหนังสือเดินทาง, การแก้ความโปร่งใส (BiRefNet HR-matting) และการปรับขนาดที่คำนึงถึงเนื้อหา (ไบนารี Go caire)
การดำเนินการที่รองรับ: การลบพื้นหลัง (rembg/BiRefNet), การลดขนาด (RealESRGAN), การเบลอใบหน้า (MediaPipe), การปรับปรุงใบหน้า (GFPGAN/CodeFormer), การลบวัตถุ (LaMa ONNX), OCR (Tesseract และ RapidOCR พร้อมรุ่น PP-OCR ONNX), การปรับสี (DDColor), การกำจัดสัญญาณรบกวน, การลบตาแดง, การฟื้นฟูภาพถ่าย, การสร้างภาพถ่ายหนังสือเดินทาง การแก้ไขความโปร่งใส (BiRefNet HR-matting) และการปรับขนาดการรับรู้เนื้อหา (Go caire binary)
สคริปต์ Python อยู่ใน `packages/ai/python/` อิมเมจ Docker ดาวน์โหลดน้ำหนักโมเดลทั้งหมดล่วงหน้าระหว่างการสร้าง เพื่อให้คอนเทนเนอร์ทำงานได้อย่างสมบูรณ์แบบออฟไลน์
สคริปต์ Python ใช้งานจริงใน `packages/ai/python/` แพ็กแบบจำลองเสริมขนาดใหญ่ได้รับการติดตั้งตามความต้องการในไดรฟ์ข้อมูล `/data/ai` แบบถาวร OCR ที่แม่นยำใช้สิ่งประดิษฐ์เฉพาะแพลตฟอร์มที่มีการลงนาม ระดับ Tesseract ในตัวไม่จำเป็นต้องดาวน์โหลดแพ็คโมเดล
### `@snapotter/shared` {#snapotter-shared}
@@ -87,7 +87,7 @@ Dependency หลัก: Fastify, Drizzle ORM (pg-core, node-postgres), Sharp, B
2. ส่วนหน้าส่ง multipart POST ไปยัง `/api/v1/tools/:section/:toolId` พร้อมไฟล์และการตั้งค่า
3. เส้นทาง API ตรวจสอบอินพุตด้วย Zod จากนั้นส่งต่อการประมวลผล
4. สำหรับเครื่องมือมาตรฐาน งานจะถูกจัดคิวไปยัง BullMQ pool ที่เหมาะสม (image, media หรือ docs ตามรูปแบบ) worker BullMQ ในกระบวนการจะปรับทิศทางภาพอัตโนมัติตามเมทาดาทา EXIF, รันฟังก์ชันการประมวลผลของเครื่องมือ และส่งคืนผลลัพธ์
5. สำหรับเครื่องมือ AI บริดจ์ TypeScript จะส่งคำขอไปยัง Python dispatcher ที่คงอยู่ (หรือสร้าง subprocess ใหม่เป็นทางเลือกสำรอง) รอให้เสร็จ แล้วอ่านไฟล์เอาต์พุต
5. สำหรับเครื่องมือ AI ส่วนใหญ่ สะพาน TypeScript จะส่งคำขอไปยัง Python dispatcher แบบถาวร Fast OCR จะเรียกใช้ Tesseract แทน และ OCR ที่แม่นยำจะเริ่มต้นการดำเนินการที่ปักหมุดไว้จากรุ่น OCR ที่ไม่เปลี่ยนรูปแบบที่ใช้งานอยู่ ระดับ OCR ที่ร้องขอได้รับการแก้ไขที่ทางเข้าและจะไม่มีการเปลี่ยนแปลงอย่างเงียบๆ ในระหว่างการดำเนินการ
6. ความคืบหน้าของงานจะถูกบันทึกลงในตาราง `jobs` ใน PostgreSQL เพื่อให้สถานะอยู่รอดจากการรีสตาร์ตคอนเทนเนอร์ การอัปเดตแบบเรียลไทม์ถูกส่งผ่าน SSE ที่ `/api/v1/jobs/:jobId/progress`
7. API ส่งคืน `jobId` และ `downloadUrl` ผู้ใช้ดาวน์โหลดไฟล์ที่ประมวลผลแล้วจาก `/api/v1/download/:jobId/:filename`