pulpie-webgpu / DOCS /OVERVIEW.md
sizzlebop's picture
feat: add edge proxy routing and update URL fetcher
8286b6d
|
Raw History Blame Contribute Delete
7.36 kB
# Pulpie WebGPU Technical Overview
This document describes the architecture, pipeline stages, and execution flow of the Pulpie WebGPU web application.
## High-Level Architecture
Pulpie WebGPU runs the 210M-parameter EuroBERT token classification model entirely inside the user's browser via WebGPU. It eliminates the need for server-side Python backends, CUDA installations, or remote inference APIs.
```text
+-------------------------------------------------------------------------+
| Browser Window |
| |
| [Input: URL or HTML] |
| | |
| v |
| [DOMParser & Sanitization] -> Cleans scripts, styles, metadata |
| | |
| v |
| [Block Extractor] ----------> Tags semantic blocks with _item_id |
| | |
| v |
| [EuroBERT Tokenizer] -------> Encodes block text, injects <|sep|> |
| | |
| v |
| [Chunk Packer] -------------> Bundles blocks up to 1,024-2,048 tokens |
| | |
| v |
| [WebGPU ONNX Runtime] ------> Executes model.onnx via FP32 shaders |
| | |
| v |
| [Logit Evaluator] ----------> Argmax at <|sep|> indices (1=main, 0=drop) |
| | |
| v |
| [DOM Reconstructor] --------> Retains kept blocks, drops boilerplate |
| | |
| v |
| [Turndown Service] ---------> Converts cleaned HTML to Markdown |
| | |
| v |
| [Output Views] -------------> Reader Preview, Markdown, Clean HTML |
+-------------------------------------------------------------------------+
```
## Core Pipeline Stages
### 1. HTML Simplification and Block Segmentation (`html-simplifier.js`)
* Uses browser-native `DOMParser` to build a clean document object model.
* Strips non-content elements: `script`, `style`, `noscript`, `iframe`, `frame`, `meta`, `link`, and hidden CSS nodes (`display: none`, `visibility: hidden`).
* Rewrites relative `src` and `href` attributes to absolute URLs against the page's base origin so that images continue rendering properly in Markdown.
* Traverses the DOM tree to extract semantic content blocks: headings (`h1` through `h6`), paragraphs (`p`), preformatted code (`pre`), blockquotes, list items (`li`), and tables.
* Assigns an incremental `_item_id` attribute (e.g. `_item_id="0"`) to each extracted block.
### 2. Tokenization and Chunking (`tokenizer.js` & `chunker.js`)
* Uses `@huggingface/transformers` to run the EuroBERT fast tokenizer directly in JavaScript.
* Identifies boundary token IDs:
* BOS: `<|begin_of_text|>` (128000)
* EOS: `<|end_of_text|>` (128001)
* SEP: `<|sep|>` (128256)
* Packs blocks into contiguous chunks conforming to the 8,192 token limit:
`[BOS] block_0 [<|sep|>] block_1 [<|sep|>] ... block_N [<|sep|>] [EOS]`
* Keeps a parallel array tracking which original block indices correspond to each chunk.
### 3. WebGPU Neural Inference (`webgpu-engine.js`)
* Evaluates `navigator.gpu` and requests an adapter using the `high-performance` power preference.
* Verifies whether the hardware supports the `shader-f16` WGSL extension.
* Prepares two 64-bit integer tensors for ONNX Runtime:
* `input_ids`: Shape `[1, sequence_length]`, containing the packed token IDs.
* `attention_mask`: Shape `[1, sequence_length]`, initialized to ones.
* Runs the model forward pass on the GPU:
`const outputMap = await session.run({ input_ids, attention_mask });`
* Returns a `Float32Array` of logits with shape `[1, sequence_length, 2]`.
### 4. Delimiter Logit Evaluation
* Finds the exact position of every `<|sep|>` token in the sequence.
* For each delimiter position `p`:
* Evaluates `logitMain = logits[p * 2 + 1]` versus `logitOther = logits[p * 2 + 0]`.
* If `logitMain > logitOther`, the block is classified as primary content (`main`).
* Otherwise, the block is classified as extraneous boilerplate (`other`).
### 5. Content Reconstruction and Markdown Conversion (`reconstructor.js`)
* Clones the tagged DOM and identifies all elements tagged with an `_item_id` that received a `main` classification.
* Marks those elements, their descendants, and their ancestors up to the document body to be retained.
* Prunes all other elements from the tree.
* Strips zero-sized tracking pixels and 1x1 spacer images.
* Passes the cleaned HTML to a configured `TurndownService` instance that applies GitHub-flavored Markdown rules (fenced code blocks, tables, and images).
### 6. Persistent Model Caching (`model-cache.js`)
* Interacts with the browser's native `CacheStorage` API (`caches.open('pulpie-onnx-v2')`).
* Intercepts downloads of `model.onnx` (808 MB) and streams chunks while updating the user interface progress bar.
* Stores the resulting `Response` in cache so future sessions load in less than 200 milliseconds without network traffic.
## File Organization
| Path | Purpose | Lines of Code |
|---|---|---:|
| `index.html` | Semantic markup, modal dialogs, and layout structure | ~355 |
| `src/main.js` | Event wiring, state coordination, and execution flow | ~474 |
| `src/style.css` | Vercel-style dark charcoal theme and responsive rules | ~974 |
| `src/lib/webgpu-engine.js` | WebGPU device detection, session lifecycle, and tensor execution | ~197 |
| `src/lib/model-cache.js` | Persistent browser cache storage and download progress reporting | ~160 |
| `src/lib/tokenizer.js` | EuroBERT fast tokenizer wrapper and special token management | ~104 |
| `src/lib/chunker.js` | Sequence packing within 1,024-2,048 token context window | ~103 |
| `src/lib/html-simplifier.js` | DOM cleaning, URL resolution, and block segmentation | ~217 |
| `src/lib/reconstructor.js` | Element pruning and HTML to Markdown conversion | ~173 |
| `src/lib/ui-renderer.js` | Results view, stats computation, and block inspection rendering | ~81 |
| src/worker.js | Cloudflare Worker edge handler with /api/proxy and static asset routing | ~80 |
| src/lib/url-fetcher.js | Webpage fetching with dedicated edge proxy and fallback | ~95 |
| `src/lib/samples.js` | Realistic HTML test documents for offline benchmarking | ~135 |