|
Download docs/postprocessing.md from iapp/OpenThai2.0-OCR-Markdown: direct link, hf CLI and curl.
- Browser
- Download file 5.19 kB
-
https://huggingface.co/iapp/OpenThai2.0-OCR-Markdown/resolve/main/docs/postprocessing.md
- Command line
-
hf download hf://iapp/OpenThai2.0-OCR-Markdown/docs/postprocessing.md
-
curl -L -o postprocessing.md https://huggingface.co/iapp/OpenThai2.0-OCR-Markdown/resolve/main/docs/postprocessing.md
5.19 kB
| # Parse documents and export tables | |
| These helpers use predictions and page images; they do not load benchmark answers. | |
| ## Downloaded helpers | |
| With [the native vLLM server](serving.md#native-dflash2) running: | |
| ```bash | |
| python -m pip install beautifulsoup4 Pillow numpy httpx | |
| ``` | |
| No serving plugin is required. Add the downloaded repository to Python's import path: | |
| ```python | |
| import sys | |
| sys.path.insert(0, "./parse35") | |
| from nemotron_parse.inference import DocumentParser | |
| def main(): | |
| with DocumentParser( | |
| base_url="http://localhost:8000/v1", model="nemotron-parse", | |
| ) as parser: | |
| documents = parser.parse_many( | |
| ["one.png", "two.png"], mode="triple", | |
| concurrency=128, triple_regions="union", | |
| ) | |
| for document in documents: | |
| print(document["markdown"]) | |
| print(document["blocks"]) | |
| if __name__ == "__main__": | |
| main() | |
| ``` | |
| `single` parses each full page. `double` also refines predicted Table/Chart crops. | |
| `triple` adds independent detection and refines the detector/parser region union. | |
| `parse_many` overlaps parsing and detection, submits crops as they become ready, | |
| and shares one concurrency window across stages. Put multiprocessing entry points | |
| under the main guard. The one-page `parse`, `parse_double` and `parse_triple` | |
| convenience methods execute their dependent stages serially. | |
| The default alternatives merge retains differing overlapping table/chart hypotheses. | |
| Use `DocumentParser(merge_policy="guarded")` for conservative replacement and a | |
| single selected hypothesis; this can discard correct alternatives. Stage responses | |
| remain available in `document["stages"]`. | |
| ## Convert an existing prediction | |
| ```python | |
| from nemotron_parse import postprocess_document, PostprocessOptions | |
| from postprocessing import postprocess_text | |
| options = PostprocessOptions( | |
| infer_headers=True, render_charts=True, | |
| split_chart_value_percent=True, relocate_chart_captions=True, | |
| ) | |
| document = postprocess_document(raw_output, image_size=image.size, options=options) | |
| table = next(b for b in document["blocks"] if b["class"] == "Table") | |
| print(postprocess_text(table["text"], cls="Table", table_format="csv")) | |
| print(postprocess_text(table["text"], cls="Table", table_format="json_hierarchical")) | |
| ``` | |
| Blocks retain class, normalized `bbox`, literal `text` and rendered `content`. | |
| `image_size=(width,height)` adds clipped pixel boxes. Document Markdown uses | |
| HTML tables to preserve merged cells. `HTML` and `json_hierarchical` preserve | |
| cell spans; `markdown`, `csv` and record `json` are flat exports that expand spans. | |
| `latex` retains the predicted table representation. Headerless tables retain | |
| their first data row; duplicate column names are disambiguated. | |
| Set any presentation option above to `False` to disable it. Caption association | |
| moves existing text; value/percentage splitting separates existing predictions | |
| and does not calculate values. Raw block text remains available. Malformed tables | |
| are retained and reported in warnings rather than forced into a lossy row splitter. | |
| For strict output schemas, select fields after a full-structure parse; prompt | |
| switches can leave residual structural tokens. | |
| ## Draw predicted boxes | |
| Continue from the prediction conversion above to save an image overlay: | |
| ```python | |
| from PIL import ImageDraw | |
| overlay = image.copy() | |
| draw = ImageDraw.Draw(overlay) | |
| for block in document["blocks"]: | |
| if block.get("bbox_pixels"): | |
| draw.rectangle(block["bbox_pixels"], outline="red", width=2) | |
| overlay.save("prediction.png") | |
| ``` | |
| Use the same image dimensions supplied to `postprocess_document`. This recipe | |
| draws the predicted boxes without changing their geometry or the source image. | |
| ## Completion and prepared batches | |
| Strict generation handling is the default. Token-limited, empty, failed or | |
| filtered output raises `GenerationError`. If partial results are useful, pass | |
| `allow_partial=True`: affected documents have `complete=False` and | |
| `generation_warnings`; truncated crops are excluded from refinement. Transport | |
| errors and empty responses still raise. Do not count partial pages as completed. | |
| For repeated processing of the same page images: | |
| ```python | |
| prepared = parser.prepare(page_images, workers=8) | |
| result = parser.parse_prepared( | |
| prepared, mode="triple", concurrency=128, postprocess_workers=8, | |
| triple_regions="union", schedule="pipelined", allow_partial=True, | |
| ) | |
| print(result.metrics["inference_pages_per_second"]) | |
| print(result.metrics["complete_inference_pages_per_second"]) | |
| ``` | |
| Run this inside the guarded main function while `parser` is open. Preparation is | |
| reported separately. The inference clock includes model/HTTP calls, queueing and | |
| dependent crop preparation; final rendering and serialization are reported | |
| separately. Use pipeline rates when end-to-end merge/render cost matters. Stage | |
| spans overlap and must not be added together. | |
| For crop margins, generation controls, a loaded Transformers backend, CLI use, | |
| and historical validation, see the [extended reference](postprocessing-reference.md). | |
| The CLI can run from downloaded source as `python -m nemotron_parse.inference`; | |
| installing the serving plugin is unnecessary for that invocation. | |