Skip to content
Merged
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
2 changes: 0 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ jobs:
- uses: astral-sh/setup-uv@v7

- name: Build wheel and sdist
working-directory: pulpie
run: uv build

- name: Publish to PyPI
working-directory: pulpie
run: uv publish
4 changes: 1 addition & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-dependency-glob: "pulpie/pyproject.toml"
cache-dependency-glob: "pyproject.toml"

- name: Install pulpie with dev + markdown extras
working-directory: pulpie
run: |
uv venv
uv pip install -e ".[dev,markdown]"

- name: Run simplify/reconstruct parity tests
working-directory: pulpie
run: uv run --no-sync pytest tests -n auto -q
File renamed without changes.
File renamed without changes.
76 changes: 70 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,76 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="pulpie/assets/banner-dark.png">
<img alt="pulpie" src="pulpie/assets/banner-light.png" width="440">
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/chonkie-inc/pulpie/main/assets/banner-dark.png">
<img alt="pulpie" src="https://raw.githubusercontent.com/chonkie-inc/pulpie/main/assets/banner-light.png" width="440">
</picture>
</p>

<p align="center">
Fast content extraction from HTML using encoder models — 16x faster than autoregressive approaches at the same quality.
</p>
Fast content extraction from HTML using encoder models. 16x faster than autoregressive approaches at the same quality.

## Install

```bash
pip install pulpie
```

For markdown output:
```bash
pip install pulpie[markdown]
```

## Usage

```python
from pulpie import Extractor

extractor = Extractor() # downloads pulpie-orange-small (210M) on first use

result = extractor.extract(html)
print(result.markdown) # clean markdown
print(result.html) # clean HTML
print(result.n_main) # number of content blocks
print(result.n_other) # number of boilerplate blocks
```

## Models

| Model | Size | ROUGE-5 | Speed (L4) |
|-------|------|---------|------------|
| `orange-small` | 210M | 0.864 | 15 pps |
| `orange-base` | 610M | 0.849 | ~6 pps |
| `orange-large` | 2.1B | 0.862 | ~2 pps |

`orange-small` is the default and recommended model — it matches the 2.1B teacher at 1/10th the size.

```python
# Use a specific model
extractor = Extractor(model="orange-large")

# Use a custom model path
extractor = Extractor(model="path/to/your/model")

# Force CPU
extractor = Extractor(device="cpu")
```

## How it works

Pulpie classifies each HTML block as "main content" or "boilerplate" using a bidirectional encoder. The pipeline:

1. **Simplify** — Strip scripts, styles, normalize HTML (via MinerU-HTML)
2. **Chunk** — Pack blocks into sequences separated by `<|sep|>` tokens
3. **Classify** — Single encoder forward pass classifies all blocks simultaneously
4. **Reconstruct** — Extract content blocks, convert to markdown

## Performance

On 500 real Common Crawl pages (NVIDIA L4 GPU):

- **15.1 pages/sec** (single GPU, 210M model)
- **$6,500** to clean 1 billion pages
- **16.4x faster** than Dripper (autoregressive) on the same hardware
- **433 MB** VRAM — fits on any GPU

## License

The Python package lives in [`pulpie/`](pulpie/) — see its [README](pulpie/README.md) for install and usage.
Apache 2.0
File renamed without changes
File renamed without changes
File renamed without changes
76 changes: 0 additions & 76 deletions pulpie/README.md

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion pulpie/tests/_oracle/SOURCE.md → tests/_oracle/SOURCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ tests. It is not shipped in the pulpie wheel (the package is scoped to `src/` vi
Only `mineru_html/process/{html_utils,simplify_html,map_to_main}.py` and their
light dependencies (`base.py`, `constants.py`, `exceptions.py`) are exercised; the
test conftest loads them via a synthetic-module shim (see
`pulpie/tests/conftest.py`) to avoid importing the full package's vllm/transformers
`tests/conftest.py`) to avoid importing the full package's vllm/transformers
inference stack.

To refresh: re-clone upstream, copy `mineru_html/` here, update the commit SHA above.
2 changes: 1 addition & 1 deletion pulpie/tests/conftest.py → tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def oracle_extract_main():

def _fixture_paths():
here = os.path.dirname(os.path.abspath(__file__))
html_dir = os.path.normpath(os.path.join(here, "..", "..", "eval", "html"))
html_dir = os.path.normpath(os.path.join(here, "..", "eval", "html"))
return sorted(
os.path.join(html_dir, f) for f in os.listdir(html_dir) if f.endswith(".html")
)
Expand Down
4 changes: 2 additions & 2 deletions pulpie/tests/gpu/AGENTS.md → tests/gpu/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ models were trained for. No prior session context is needed; everything is here.

pulpie's `simplify.py` was rewritten to faithfully reproduce MinerU-HTML's
`simplify_html` output (the format the Orange models were distilled on). Offline
byte-parity tests already pass (`pytest pulpie/tests -n auto`, CPU-only). This
byte-parity tests already pass (`pytest tests -n auto`, CPU-only). This
runbook is the **end-to-end quality gate**: run pulpie standalone and verify the
score moved from the old **0.731 ROUGE-5** to **~0.862** (parity with MinerU's own
pipeline). Hitting ~0.862 means the port closed the gap and pulpie no longer needs
Expand Down Expand Up @@ -112,7 +112,7 @@ python eval_simplify_port_gate.py
checks:
- `python -c "from pulpie.simplify import simplify; print(simplify('<html><body><nav>x</nav><p>hi</p></body>')[0])"`
— output should drop `<nav>` and show `_item_id` on the `<p>`.
- Confirm `pytest pulpie/tests -n auto` is green (byte-parity holds).
- Confirm `pytest tests -n auto` is green (byte-parity holds).
- Confirm the installed `pulpie` is this branch (not a stale PyPI build).

Report back: model used, page count, mean ROUGE-5, and (if available) the
Expand Down
File renamed without changes.
File renamed without changes.