feat: complete lexicon anomalies heal, merge grammatical duplicates and add local Xiaomi-OCR documentation

This commit is contained in:
2026-10-11 17:40:07 +05:00
parent 88a6204f1b
commit 4d212e1a9a
3 changed files with 1635 additions and 2076 deletions
+94
View File
@@ -0,0 +1,94 @@
# Локальный OCR-сервис Xiaomi-OCR-0
## Контекст
На этой машине развёрнута и работает локальная OCR-модель Xiaomi-OCR-0 (SeerRay-Lab/Xiaomi-OCR-0). Это vision-language модель на 0.8B параметров (основа — Qwen3.5-0.8B, архитектура Qwen3_5ForConditionalGeneration). Она умеет:
- Разбор документов → Markdown (таблицы в OTSL → HTML, формулы в LaTeX, порядок чтения).
- KIE (извлечение ключевой информации) → JSON по заданной схеме полей.
- VQA — короткие ответы на вопросы по изображению.
- Разбор отдельных регионов: текст, таблица, формула.
- Сканы, чеки, формулы (в т.ч. рукописные), рукописный текст, каллиграфию, PDF (через рендер страниц).
- Всё работает только локально, без облачных API. Ключ API не нужен.
## Окружение
| Параметр | Значение |
|---|---|
| ОС | Ubuntu 26.04, Linux x86_64 |
| GPU | NVIDIA RTX 4060 Laptop, 8 ГБ VRAM (vLLM занимает ~75%) |
| Каталог проекта | `/home/alexives/OCR Xiaomi neuro` (в пути есть пробел — всегда бери его в кавычки) |
| Python venv | `/home/alexives/OCR Xiaomi neuro/.venv` → симлинк на `/mnt/data/alexives_cache/xiaomi_ocr_venv` (Python 3.12) |
| Кэш HF (веса модели) | `/mnt/data/alexives_cache/huggingface` |
| Движок инференса | vLLM 0.31.0, CUDA 13 |
| Обязательная переменная окружения | `VLLM_USE_FLASHINFER_SAMPLER=0` (без неё vLLM падает: нет системного nvcc/CUDA toolkit для JIT FlashInfer) |
> На системном разделе `/` мало места (~3.7 ГБ). Любые тяжёлые кэши и зависимости клади в `/mnt/data/alexives_cache/`.
## Запуск и остановка
```bash
"/home/alexives/OCR Xiaomi neuro/start.sh" # запускает vLLM (:8000) и веб-демо (:8787), ждёт готовности
"/home/alexives/OCR Xiaomi neuro/stop.sh" # останавливает оба процесса
```
Холодный старт vLLM занимает ~2 минуты (torch.compile + захват графов CUDA). Перед запросами опрашивай `GET /v1/models`, пока не придёт ответ.
Логи: `vllm.log` и `demo.log` в каталоге проекта.
## Сервисы
| Сервис | URL | Назначение |
|---|---|---|
| vLLM (OpenAI-совместимый API) | `http://127.0.0.1:8000/v1` | Прямой инференс. Основная точка интеграции. |
| Веб-демо + REST | `http://127.0.0.1:8787` | UI в браузере и упрощённый REST с готовой пред- и постобработкой |
- Имя модели в запросах: `SeerRay-Lab/Xiaomi-OCR-0` (именно так, с префиксом).
- Проверка готовности: `curl -s http://127.0.0.1:8000/v1/models` и `curl -s http://127.0.0.1:8787/api/health` (`"ready": true`).
- Сервисы слушают только loopback (`127.0.0.1`). Не открывай их наружу.
## Вариант A: прямой вызов vLLM (рекомендуется)
### Обязательные правила запроса
1. Ровно одно изображение на запрос, сначала изображение, потом текст, в одном user-сообщении.
2. Изображение передаётся как data-URL: `data:image/png;base64,...`.
3. Thinking-режим выключен: `"chat_template_kwargs": {"enable_thinking": false}`.
4. Жадное декодирование (как в эталонном пайплайне):
`"temperature": 0, "top_p": 0.8, "presence_penalty": 0.0, "repetition_penalty": 1.0`
5. `max_tokens`: 4096 по умолчанию для целой страницы (максимум 16384, но картинка + промпт + вывод должны влезть в контекст 16384).
6. Если `finish_reason == "length"` — вывод обрезан: увеличь `max_tokens` или уменьши картинку / раздели её на части.
7. Без системного сообщения. Промпты — на английском, дословно.
### Промпты (дословно)
- **Целая страница документа → Markdown:**
`Extract all information from the main body of the document image and represent it in markdown format, ignoring headers and footers. Tables should be expressed in OTSL format, formulas in the document should be represented using LATEX format, and the parsing should be organized according to the reading order.`
- **Регион с текстом / заголовком:**
`Extract the text in the image.`
- **Регион с таблицей:**
`Parse the table in the image into OTSL.`
- **Регион с формулой:**
`Identify the formula in the image and represent it using LATEX format.`
- **KIE с известными полями:**
`Extract key information in the image`
`Please output the key information in JSON format according to the following schema:`
`{"company": "", "date": "", "total": ""}`
- **KIE без заданных полей:**
`Extract the key information from the document image as a JSON object. Use concise field names. Return JSON only; use an empty string for missing values.`
- **VQA:**
`<ВОПРОС>
Answer the question using a single word or phrase.`
### Постобработка
Таблицы приходят в OTSL (токены `<fcel>`, `<ecel>`, `<lcel>`, `<ucel>`, `<xcel>`, `<nl>`). Конвертируй в HTML:
```python
import sys; sys.path.insert(0, "/home/alexives/OCR Xiaomi neuro")
from postprocess.otsl import convert_otsl_to_html
from postprocess.document import finalize_document
md = finalize_document(raw_model_text)
```
## Вариант B: REST веб-демо (:8787)
POST `http://127.0.0.1:8787/api/ocr`, `Content-Type: application/json`:
```json
{
"task": "document",
"image_base64": "<base64 или data:image/...;base64,...>",
"image_mime": "image/jpeg",
"max_tokens": 4096,
"temperature": 0
}
```
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -73937,29 +73937,29 @@
"state_destructive": "Перемена места и рождение, которые путают с вечным переездом.",
"culture_sumer_light": "",
"culture_sumer_shadow": "",
"culture_egypt_light": "",
"culture_egypt_light": "[Дж. Купер · «Энциклопедия символов»]: «У египтян аист олицетворял сыновнюю почтительность, так как считалось, что он кормит своих родителей в их старости.»",
"culture_egypt_shadow": "",
"culture_kabbalah_light": "",
"culture_kabbalah_shadow": "",
"culture_antiquity_light": "[Джек Тресиддер · «Словарь символов»]: «На Востоке - популярная эмблема долголетия, а в даосизме - бессмертия. Во многих культурах аист символизирует дочернюю и сыновнюю преданность из-за поверья, что аисты кормят своих родителей, как и своих детей. Эта трогательная забота и ассоциация с новой жизнью (аисты прилетают весной) явились причиной того, что аист стал священной птицей древнегреческой богини Геры (в римской...»",
"culture_antiquity_light": "[Джек Тресиддер · «Словарь символов»]: «На Востоке - популярная эмблема долголетия, а в даосизме - бессмертия. Во многих культурах аист символизирует дочернюю и сыновнюю преданность из-за поверья, что аисты кормят своих родителей, как и своих детей. Эта трогательная забота и ассоциация с новой жизнью (аисты прилетают весной) явились причиной того, что аист стал священной птицей древнегреческой богини Геры (в римской...»\n\n[Дж. Купер · «Энциклопедия символов»]: «В греческих мистериях богиня аистов изображалась в виде женщины — подательницы жизни, кормилицы и являлась атрибутом Геры. У римлян аист символизировал почтительность, сыновнюю привязанность и считался атрибутом Юноны.»",
"culture_antiquity_shadow": "",
"culture_celtic_light": "",
"culture_celtic_shadow": "",
"culture_nordic_light": "",
"culture_nordic_shadow": "",
"culture_slavic_light": "",
"culture_slavic_light": "[Дж. Купер · «Энциклопедия символов»]: «В славянских поверьях и христианской традиции аист символизирует целомудрие, чистоту, благочестие, покровительство семейному очагу и наступление весны.»",
"culture_slavic_shadow": "",
"culture_india_light": "",
"culture_india_shadow": "",
"culture_persia_light": "",
"culture_persia_shadow": "",
"culture_china_light": "",
"culture_china_light": "[Дж. Купер · «Энциклопедия символов»]: «У китайцев аист означает долгожительство, счастливую и умиротворенную старость, сыновнюю почтительность достойного, чуждого соблазнов, живущего в уединении отшельника.»",
"culture_china_shadow": "",
"culture_japan_light": "",
"culture_japan_shadow": "",
"culture_islam_light": "",
"culture_islam_shadow": "",
"culture_hermetic_light": "",
"culture_hermetic_light": "[Дж. Купер · «Энциклопедия символов»]: «Наряду с орлом и ибисом, аист уничтожает зловещих рептилий и является потому солнечной птицей. Но, как существо, связанное с водой и рыбой, он ассоциируется с водами творения. \"Приносимые аистом\" дети в виде эмбрионов находятся в лоне Матери-Земли и в водах творения, где их и находят при ловле рыбы аисты. Символизирует приход весны и новой жизни, благовещенская птица.»",
"culture_hermetic_shadow": "",
"culture_mesoamerica_light": "",
"culture_mesoamerica_shadow": "",
@@ -73973,7 +73973,7 @@
"will_vector": "Ты несёшь новое в гнездо или только меняешь крышу?",
"shadow_warning": "Перемена места и рождение, которые путают с вечным переездом."
},
"filled_count": 14,
"filled_count": 18,
"is_complete": false,
"updated_at": "2026-10-08T13:39:29.998946",
"illustrations": []