Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,51 @@ Unlimited OCR Vendor images with a side longer than 8192 px are resized
proportionally before upload. Returned layout coordinates are mapped back to the
original image size.

### GLM-OCR SDK Service

Use this backend with the GLM-OCR SDK's full structured parsing service, not its
underlying MLX/vLLM recognition endpoint:

```python
from doc_page_extractor import (
GLMOCRServiceConfig,
create_glm_ocr_service_page_extractor,
)

extractor = create_glm_ocr_service_page_extractor(
GLMOCRServiceConfig(
endpoint_url="http://127.0.0.1:5002/glmocr/parse",
api_key=None,
timeout_seconds=180,
)
)
```

The adapter uploads page bytes as a data URL, converts the SDK's normalized
0–1000 `bbox_2d`/polygon geometry to input-image pixels, and preserves the
SDK formatter's `index` reading order and native labels. It maps returned
text, titles, captions, tables, formulas, images, and footnotes into the
standard structured page model. The service is externally managed and does not
support model downloads or multi-stage redaction. Token limits are rejected
because the SDK service currently returns no usable token usage/limit contract;
HTTP timeouts and service/geometry errors are propagated.

Only labels actually returned by the SDK can be mapped. The SDK repository's
shipped server configuration marks `footnote`, `header`, `footer`, `number`,
`aside_text`, and `reference` as `abandon`; configure the SDK service's
`pipeline.layout.label_task_mapping` to retain any of these regions before
using them. Also disable `pipeline.result_formatter.enable_merge_text_blocks`
and `enable_merge_formula_numbers` to retain region-level geometry. The adapter
uses `native_label` before display-label fallback and removes SDK-added Markdown
heading markers from title text. It cannot recover labels discarded by that
service. SDK failures/empty recognition results may already have been filtered
out before the response reaches this adapter; inspect representative outputs.

The adapter was exercised against SDK source revision
`cef4d0ea120d1741f5cefe8985eee45f6c8eff1d` (0.1.5), MLX-VLM 0.7.2, and CPU
PP-DocLayoutV3 on Apple Silicon. A sanitized real synthetic-page response is
stored in `tests/fixtures/glmocr/`. Regular tests use no models or network.

## Extraction

All backends return the same `PageExtractor` shape:
Expand Down
6 changes: 6 additions & 0 deletions doc_page_extractor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

_LAZY_EXPORTS = {
"AbortError": ("extraction_context", "AbortError"),
"GLMOCRServiceAdapter": ("adapters", "GLMOCRServiceAdapter"),
"GLMOCRServiceConfig": ("adapters", "GLMOCRServiceConfig"),
"DeepSeekOCR2VendorAdapter": ("adapters", "DeepSeekOCR2VendorAdapter"),
"DeepSeekOCR2VendorConfig": ("adapters", "DeepSeekOCR2VendorConfig"),
"DeepSeekBackend": ("types", "DeepSeekBackend"),
Expand All @@ -23,6 +25,7 @@
"UnlimitedModelOCRAdapter": ("adapters", "UnlimitedModelOCRAdapter"),
"UnlimitedOCRVendorAdapter": ("adapters", "UnlimitedOCRVendorAdapter"),
"UnlimitedOCRVendorConfig": ("adapters", "UnlimitedOCRVendorConfig"),
"create_glm_ocr_service_page_extractor": ("extractor", "create_glm_ocr_service_page_extractor"),
"create_deepseek_ocr_page_extractor": ("extractor", "create_deepseek_ocr_page_extractor"),
"create_page_extractor_with_adapter": ("extractor", "create_page_extractor_with_adapter"),
"create_deepseek_ocr2_vendor_page_extractor": ("extractor", "create_deepseek_ocr2_vendor_page_extractor"),
Expand All @@ -34,6 +37,9 @@

__all__ = [
"plot",
"create_glm_ocr_service_page_extractor",
"GLMOCRServiceConfig",
"GLMOCRServiceAdapter",
"create_deepseek_ocr_page_extractor",
"create_page_extractor_with_adapter",
"create_deepseek_ocr_vendor_page_extractor",
Expand Down
6 changes: 6 additions & 0 deletions doc_page_extractor/adapters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# pylint: disable=undefined-all-variable

_LAZY_EXPORTS = {
"GLMOCRServiceAdapter": ("glmocr", "GLMOCRServiceAdapter"),
"GLMOCRServiceConfig": ("glmocr", "GLMOCRServiceConfig"),
"parse_glm_ocr_layouts": ("glmocr", "parse_glm_ocr_layouts"),
"DeepSeekOCR2VendorAdapter": ("deepseek", "DeepSeekOCR2VendorAdapter"),
"DeepSeekOCR2VendorConfig": ("deepseek", "DeepSeekOCR2VendorConfig"),
"DeepSeekOCRVendorAdapter": ("deepseek", "DeepSeekOCRVendorAdapter"),
Expand All @@ -15,6 +18,9 @@
}

__all__ = [
"GLMOCRServiceAdapter",
"GLMOCRServiceConfig",
"parse_glm_ocr_layouts",
"DeepSeekOCR2VendorAdapter",
"DeepSeekOCR2VendorConfig",
"DeepSeekOCRVendorAdapter",
Expand Down
Loading