# Docling Testing

## Using Git on Forgejo Server

## The Forgejo Server

### Create project

http://192.168.1.210:3000/stephen/137_Docing-Test

this creates an empty repository

### On remote site MacBook

Open terminal on 01_Projects in the terminal 

```zsh
stephenlohning@Scotty 01_Projects % git clone http://192.168.1.210:3000/stephen/137_Docing-Test
Cloning into '137_Docing-Test'...
warning: You appear to have cloned an empty repository.
```
This creates a directory called "137_Docing-Test" the same as the repository. There only one file in the directory

```zsh
stephenlohning@Scotty 137_Docing-Test % ls -la
total 0
drwxr-xr-x    3 stephenlohning  staff    96 May 29 19:42 .
drwxr-xr-x@ 158 stephenlohning  staff  5056 May 29 19:42 ..
drwxr-xr-x    9 stephenlohning  staff   288 May 29 19:42 .git
stephenlohning@Scotty 137_Docing-Test % git remote -v
origin  http://192.168.1.210:3000/stephen/137_Docing-Test (fetch)
origin  http://192.168.1.210:3000/stephen/137_Docing-Test (push)
```

```zsh
stephenlohning@Scotty 137_Docing-Test % git branch -M main
stephenlohning@Scotty 137_Docing-Test % touch .gitignore
stephenlohning@Scotty 137_Docing-Test % git config --global push.followTags true
stephenlohning@Scotty 137_Docing-Test % 
```
### Create structure you want, template 

```zsh
stephenlohning@Scotty 137_Docing-Test % tree
.
├── Readme.md
└── doc
    ├── Notes.md
    ├── Notes.pdf
    └── images

3 directories, 3 files
```

## Check uv version and upgrade


- This I did in VS Code terminal

```zsh
stephenlohning@Scotty 137_Docing-Test % uv --version
uv 0.5.20 (1c17662b3 2025-01-15)
stephenlohning@Scotty 137_Docing-Test % uv self update
info: Checking for updates...
success: Upgraded uv from v0.5.20 to v0.11.17! https://github.com/astral-sh/uv/releases/tag/0.11.17
stephenlohning@Scotty 137_Docing-Test % 
```
### setting up uv

```zsh
stephenlohning@Scotty 137_Docing-Test % uv init
Initialized project `137-docing-test`
stephenlohning@Scotty 137_Docing-Test % 
```
### check what version of python are avainable

```zsh
tephenlohning@Scotty 137_Docing-Test % uv python list  
cpython-3.15.0b1-macos-aarch64-none                 <download available>
cpython-3.15.0b1+freethreaded-macos-aarch64-none    <download available>
cpython-3.14.5-macos-aarch64-none                   /opt/homebrew/bin/python3.14 -> ../Cellar/python@3.14/3.14.5/bin/python3.14
cpython-3.14.5-macos-aarch64-none                   /opt/homebrew/bin/python3 -> ../Cellar/python@3.14/3.14.5/bin/python3
cpython-3.14.5-macos-aarch64-none                   /Users/stephenlohning/.pyenv/shims/python3.14
cpython-3.14.5-macos-aarch64-none                   /Users/stephenlohning/.pyenv/shims/python3
cpython-3.14.5-macos-aarch64-none                   <download available>
cpython-3.14.5+freethreaded-macos-aarch64-none      <download available>
cpython-3.13.13-macos-aarch64-none                  <download available>
cpython-3.13.13+freethreaded-macos-aarch64-none     <download available>
cpython-3.13.11-macos-aarch64-none                  /opt/homebrew/bin/python3.1

more here
```
### create virtual environment 

- uv venv --python 3.14

This creates .venv  directory, a main.py and a pyproject.toml

```zsh
stephenlohning@Scotty 137_Docing-Test % uv venv --python 3.14
Using CPython 3.14.2 interpreter at: /Users/stephenlohning/.pyenv/versions/3.14.2/bin/python3.14
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
stephenlohning@Scotty 137_Docing-Test % ls -la               
total 448
drwxr-xr-x   11 stephenlohning  staff     352 May 29 20:30 .
drwxr-xr-x@ 158 stephenlohning  staff    5056 May 29 19:42 ..
drwxr-xr-x   12 stephenlohning  staff     384 May 29 20:13 .git
-rw-r--r--    1 stephenlohning  staff       0 May 29 19:48 .gitignore
-rw-r--r--    1 stephenlohning  staff       5 May 29 20:28 .python-version
drwxr-xr-x    7 stephenlohning  staff     224 May 29 20:30 .venv
-rw-r--r--    1 stephenlohning  staff    1989 May 29 20:12 Readme.md
-rw-r--r--    1 stephenlohning  staff  212930 May 29 20:12 Readme.pdf
drwxr-xr-x    5 stephenlohning  staff     160 May 29 20:06 doc
-rw-r--r--    1 stephenlohning  staff      93 May 29 20:21 main.py
-rw-r--r--    1 stephenlohning  staff     161 May 29 20:21 pyproject.toml
```

#### pyproject.toml 
```zsh
stephenlohning@Scotty 137_Docing-Test % cat pyproject.toml 
[project]
name = "137-docing-test"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = []
stephenlohning@Scotty 137_Docing-Test % 
```
### uv add docling

The command uv add docling does two distinct things simultaneously: it executes an installation via uv, and it targets a specific, popular open-source AI package called docling.

Running this command executes the following actions:

#### 1. What uv does behind the scenes
Because you are using uv's modern project management tool, this single command handles the entire dependency lifecycle:

- Resolves Dependencies: It looks up docling on PyPI, checks all the sub-packages it requires, and resolves any version conflicts in milliseconds.

- Updates your pyproject.toml: It automatically writes docling into your project's configuration file under the dependencies list.

- Updates your uv.lock file: It locks down the exact cryptographic versions of docling and its sub-dependencies to ensure reproducibility across different machines.

- Installs into .venv: It downloads the wheels and installs them directly into your project's local virtual environment (creating the environment first if it doesn't already exist).

#### Example

```zsh
stephenlohning@Scotty 137_Docing-Test % uv add docling
Resolved 122 packages in 2.09s
      Built pylatexenc==2.10
      Built antlr4-python3-runtime==4.9.3
Prepared 99 packages in 4.59s
Installed 99 packages in 551ms
 + accelerate==1.13.0
 + annotated-doc==0.0.4
 + annotated-types==0.7.0
 + antlr4-python3-runtime==4.9.3
 + anyio==4.13.0
 + attrs==26.1.0
 + beautifulsoup4==4.14.3
 + certifi==2026.5.20
 + charset-normalizer==3.4.7
 + click==8.4.1
 + colorlog==6.10.1
 + defusedxml==0.7.1
 + dill==0.4.1
 + docling==2.96.0
 + docling-core==2.77.1
 + docling-ibm-models==3.13.2
 + docling-parse==6.2.0
 + docling-slim==2.96.0
 + et-xmlfile==2.0.0
 + faker==40.19.1
 + filelock==3.29.0
 + filetype==1.2.0
 + fsspec==2026.4.0
 + h11==0.16.0
 + hf-xet==1.5.0
 + httpcore==1.0.9
 + httpx==0.28.1
 + huggingface-hub==1.17.0
 + idna==3.17
 + jinja2==3.1.6
 + jsonlines==4.0.0
 + jsonref==1.1.0
 + jsonschema==4.26.0
 + jsonschema-specifications==2025.9.1
 + latex2mathml==3.81.0
 + lxml==6.1.1
 + markdown-it-py==4.2.0
 + marko==2.2.3
 + markupsafe==3.0.3
 + mdurl==0.1.2
 + mpire==2.10.2
 + mpmath==1.3.0
 + multiprocess==0.70.19
 + networkx==3.6.1
 + numpy==2.4.6
 + omegaconf==2.3.0
 + opencv-python==4.13.0.92
 + openpyxl==3.1.5
 + packaging==26.2
 + pandas==3.0.3
 + pillow==12.2.0
 + pluggy==1.6.0
 + polyfactory==3.3.0
 + psutil==7.2.2
 + pyclipper==1.4.0
 + pydantic==2.13.4
 + pydantic-core==2.46.4
 + pydantic-settings==2.14.1
 + pygments==2.20.0
 + pylatexenc==2.10
 + pypdfium2==5.8.0
 + python-dateutil==2.9.0.post0
 + python-docx==1.2.0
 + python-dotenv==1.2.2
 + python-pptx==1.0.2
 + pyyaml==6.0.3
 + rapidocr==3.8.1
 + referencing==0.37.0
 + regex==2026.5.9
 + requests==2.34.2
 + rich==15.0.0
 + rpds-py==2026.5.1
 + rtree==1.4.1
 + safetensors==0.7.0
 + scipy==1.17.1
 + semchunk==3.2.5
 + setuptools==81.0.0
 + shapely==2.1.2
 + shellingham==1.5.4
 + six==1.17.0
 + soupsieve==2.8.4
 + sympy==1.14.0
 + tabulate==0.10.0
 + tokenizers==0.22.2
 + torch==2.12.0
 + torchvision==0.27.0
 + tqdm==4.67.3
 + transformers==5.9.0
 + tree-sitter==0.25.2
 + tree-sitter-c==0.24.2
 + tree-sitter-javascript==0.25.0
 + tree-sitter-python==0.25.0
 + tree-sitter-typescript==0.23.2
 + typer==0.21.2
 + typing-extensions==4.15.0
 + typing-inspection==0.4.2
 + urllib3==2.7.0
 + websockets==16.0
 + xlsxwriter==3.2.9
stephenlohning@Scotty 137_Docing-Test % 
```

### Updated pyproject.toml
```zsh
cat pyproject.toml
[project]
name = "137-docing-test"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "docling>=2.96.0",
]
stephenlohning@Scotty 137_Docing-Test % 
```
### Update the main.py 

```py
# main.py
from docling.document_converter import DocumentConverter

def main():
    # Can be a local path (e.g., "docs/invoice.pdf") or a URL
   # source = "https://arxiv.org/pdf/2408.09869" 
    source = ./SpanishTextBook.pdf
    
    print("Initializing Docling pipeline...")
    converter = DocumentConverter()
    
    print("Processing document locally...")
    result = converter.convert(source)
    
    # Export cleanly to structured Markdown
    markdown_output = result.document.export_to_markdown()
    print("\n--- Parsing Successful! Sample Output: ---\n")
    print(markdown_output[:500])

if __name__ == "__main__":
    main()
```

#### Runing via uv

- uv run main.py

# We had multiple errors with Docling
## 1. The Python Version Compatibility Issue
### The Error
Initially, installing Docling failed due to deep dependency conflicts rooted in the Python environment version. The system was running Python 3.14 (an experimental/pre-release version).

```bash
Plaintext
Configuring project 137_Docing-Test...
  × No solution found when resolving dependencies:
  ╰─▶ Because docling v2.14.0 depends on numpy >=1.26.4 and <2.0.0...
      and no versions of numpy match >=1.26.4,<2.0.0 because python_version >= "3.14"
```      
### The Root Cause
Core scientific computing libraries utilized by Docling—specifically numpy (restricted to <2.0.0 by underlying models) and scipy—did not yet have pre-compiled binary wheels available for Python 3.14. Building them from source failed due to strict C-extension requirements that were incompatible with the unreleased Python runtime.

The Fix
We utilized the uv package manager to explicitly pin and enforce a stable, production-grade Python runtime environment without altering your global system configuration:

```Bash
uv init --python 3.12
```

This cleanly isolated the project to Python 3.12, instantly unlocking access to fully compiled, highly optimized binary wheels for numpy, scipy, torch, and onnxruntime.

## 2. The Metal Performance Shaders (MPS) float64 Crash
The Error
Once the environment was stable, running the document converter triggered a hard runtime crash during the Stage layout phase when processing the first page:

```zsh
TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn't support float64. Please use float32 instead.
Stage layout failed for run 1: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn't support float64.
```

### The Root Cause
Docling uses IBM's rt_detr_v2 (Real-Time DEtection TRansformer) vision model for document layout and element segmentation.

- By default, PyTorch detected the Apple Silicon M3 GPU hardware and automatically routed tensors to the MPS (Metal Performance Shaders) backend.

- Deep inside the Hugging Face transformers layout code, the model initialized a positional embedding layer using high-precision 64-bit floating-point numbers:

ω= torch.arange(pos_dim,dtype=torch.float64)
    ----------------------------------------
             pos_dim
​
 
- Because Apple's Metal shading language natively operates on 16-bit (half) and 32-bit (float) precisions to maximize unified memory bandwidth, the MPS framework physically lacks hardware support for float64 operations, causing the runtime execution to immediately fault.

## The Fix
Standard environment variables (like device="cpu" passing configurations or CUDA_VISIBLE_DEVICES="") failed because the model's internal source code bypassed them to poll the hardware directly.

We resolved this by implementing a pre-emptive monkeypatch at the absolute top of main.py before any heavy machine learning frameworks could execute their initialization loops:

```Python
import torch

# Intercept and mock PyTorch's hardware discovery backend completely
torch.backends.mps.is_available = lambda: False
torch.backends.mps.is_built = lambda: False

# Force standard CPU allocation fallback
torch.set_default_device("cpu")
```

## The Result
By blinding PyTorch to the presence of the local Metal architecture, the layout engine cleanly and safely fell back to the standard CPU processing path. This bypassed the precision limitations completely and achieved a flawless, structurally complete 9-page Markdown compilation in 36.44 seconds.