# marker-api Flask API wrapper around [marker](https://github.com/VikParuchuri/marker) — converts PDFs, DOCX, XLSX, PPTX, EPUB, images (PNG/JPG/BMP/GIF/TIFF/WEBP/HEIC), and HTML to Markdown (JSON/HTML/chunks). --- ## Quick Start ### Container (recommended) ```bash # Build and run with Podman/Docker podman build -t marker-api -f Containerfile . podman run -d --rm \ --name marker-api \ -p 8000:8000 \ -e AMD_COMPUTE=false \ -e TORCH_DEVICE=cpu \ marker-api # Or use docker-compose docker-compose up -d ``` ### Bare-metal ```bash git clone https://github.com/your-org/marker-api.git /app/marker-api pip install -e /app/marker-api/marker[full] flask gunicorn PORT=8000 python /app/marker-api/app.py ``` ### Health Check ```bash curl http://localhost:8000/health # {"status":"ok","ollama":"http://localhost:11434","torch_device":"cpu","supported_formats":["docx","epub","html","jpg",...]} ``` --- ## Endpoints ### `GET /` HTML documentation page listing all endpoints and parameters. ### `GET /health` Returns server status, torch device, supported file formats, and configuration. ### `POST /marker` Convert a single file. Accepts **multipart/form-data** or **application/json**. #### Multipart form-data ```bash curl -X POST http://localhost:8000/marker \ -F "file=@document.pdf" \ -F "output_format=markdown" \ -F "force_ocr=false" ``` When `output_format=markdown`, the response is the raw `.md` content as a file download. All other formats return JSON. #### JSON body (base64) ```bash curl -X POST http://localhost:8000/marker \ -H "Content-Type: application/json" \ -d '{ "file_b64": "", "filename": "document.pdf", "output_format": "markdown", "force_ocr": false }' ``` ### `POST /v1/conversions` Same as `/marker` but always returns JSON, wrapping the result with an `id` (UUID) field and `filename`. ### `POST /v1/files/convert` Same as `/marker` but always returns JSON with `filename`, `format`, `output`, `images_b64`, and `metadata`. --- ## Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `file` / `file_b64` | file / string | **required** | The document to convert | | `output_format` | string | `markdown` | `markdown`, `json`, `html`, `chunks` | | `force_ocr` | bool | `false` | Force OCR on all pages (fixes garbled text) | | `paginate_output` | bool | `false` | Separate pages with horizontal rules | | `page_range` | string | all | Comma-separated pages/ranges: `"0,5-10"` | | `disable_image_extraction` | bool | `false` | Skip embedded image extraction | | `processors` | string | auto | Comma-separated full module paths for custom processors | | `config_json` | string | none | Path to JSON config file | | `converter_cls` | string | auto | Full module path of converter (e.g. `marker.converters.table.TableConverter`) | | `use_llm` | bool | `false` | Use an LLM to improve accuracy | | `llm_service` | string | `marker.services.ollama.OllamaService` | LLM service class: `gemini`, `vertex`, `claude`, `openai`, `azure_openai`, `ollama` | | `block_correction_prompt` | string | none | Custom prompt for LLM block correction | | `redo_inline_math` | bool | `false` | Re-process inline math with LLM | | `strip_existing_ocr` | bool | `false` | Remove existing OCR text and re-OCR | | `debug` | bool | `false` | Enable debug logging | --- ## Supported Formats PDF, DOCX, XLSX, PPTX, EPUB, PNG, JPG, BMP, GIF, TIFF, WEBP, HEIC, HTML, HTM. --- ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `OLLAMA_HOST` | `http://localhost:11434` | Ollama instance for OCR fallback / LLM | | `DEESEEK_OCR_MODEL` | `deepseek-ocr` | OCR model name in Ollama | | `AMD_COMPUTE` | `false` | Enable AMD ROCm GPU support | | `TORCH_DEVICE` | auto | PyTorch device: `rocm`, `cuda`, `cpu` | | `MODEL_DTYPE` | `float32` | Model dtype: `float32`, `bfloat16` | | `PORT` | `8000` | Listening port | | `HOST` | `0.0.0.0` | Listening host | --- ## PowerShell Batch Script A PowerShell script (`marker-convert-powershell/marker-convert.ps1`) is provided for batch conversion. ### Usage ```powershell .\marker-convert-powershell\marker-convert.ps1 -TargetFolder .\documents # With options .\marker-convert-powershell\marker-convert.ps1 .\documents ` -Force -MaxConcurrency 8 -OutputFormat json -UseLlm -LlmService marker.services.ollama.OllamaService # Remote API .\marker-convert-powershell\marker-convert.ps1 .\documents -ApiUrl http://10.0.0.5:8000/marker ``` ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `-TargetFolder` | string | (required) | Folder to scan recursively | | `-ApiUrl` | uri | `http://localhost:8000/marker` | Marker API endpoint | | `-OutputFormat` | string | `markdown` | `markdown`, `json`, `html`, `chunks` | | `-Force` | switch | off | Overwrite existing `.md` files | | `-MaxConcurrency` | int | 4 | Concurrent workers (1-32) | | `-Timeout` | int | 300 | HTTP timeout in seconds (30-1800) | | `-PageRange` | string | "" | Page range e.g. `"0,5-10"` | | `-ForceOcr` | switch | off | Force OCR on all pages | | `-DisableImageExtraction` | switch | off | Skip image extraction | | `-UseLlm` | switch | off | Enable LLM enhancement | | `-LlmService` | string | `marker.services.ollama.OllamaService` | LLM service class | | `-Processors` | string | "" | Custom processor module paths | | `-ConfigJson` | string | "" | Path to JSON config file | | `-ConverterCls` | string | "" | Custom converter class path | The script writes a CSV report (`_marker_convert_results.csv`) next to each converted file. --- ## Deployment ### AMD GPU (ROCm) Set `AMD_COMPUTE=true` and `TORCH_DEVICE=cuda` in the container environment. #### Vega 20 / GFX906 Support (e.g., powermac) For older AMD GPU architectures like Vega 20 (GFX906), AMD dropped standard ROCm PyTorch support. This project fully supports GFX906 out of the box by using a patched GFX906 PyTorch base image (`mixa3607/pytorch-gfx906:v2.7.1-rocm-6.3.3`). To run the container on GFX906 GPUs with hardware acceleration: ```bash docker run -d --name marker-api \ --network=host \ --device /dev/kfd --device /dev/dri \ --group-add 984 --group-add 988 \ -e AMD_COMPUTE=true \ -e TORCH_DEVICE=cuda \ -e CUDA_VISIBLE_DEVICES=1 \ -e HSA_OVERRIDE_GFX_VERSION=9.0.6 \ marker-api:latest \ gunicorn --bind 0.0.0.0:8000 --workers 1 --timeout 300 --worker-class gthread --threads 4 app:app_instance ``` *Note on first run:* The very first conversion on a ROCm GPU will take 2-3 minutes as MIOpen compiles convolution kernels for your exact GPU. Subsequent runs are fully cached and take ~4-5 seconds per document. *Note on memory:* If other services (e.g., llama-servers) are utilizing GPU 0, restrict `marker-api` to GPU 1 (`CUDA_VISIBLE_DEVICES=1`) and use a single worker (`--workers 1`) to prevent HIP Out-Of-Memory errors. ### CPU-only ```bash TORCH_DEVICE=cpu AMD_COMPUTE=false podman run ... marker-api ``` ### GPU (CUDA) Override the PyTorch index URL during build, or use the existing ROCm image with `TORCH_DEVICE=cuda`. --- ## Response Codes | Code | Meaning | |------|---------| | `200` | Successful conversion (markdown returned as file download, others as JSON) | | `400` | Missing file or invalid body | | `500` | Conversion error (details in JSON body) | Error responses have the shape: ```json {"success": false, "error": "error message"} ```