CANVAS is a render-aware, parser-aligned, stroke-wise adaptive sampler for text-to-SVG generation. This repository contains the H1 configuration described in the paper: one parser-complete future stroke, pilot/fresh separation, influence- and cost-aware allocation, importance correction, leading ratio-bias correction, categorical commits, and defensive positive-mass fallbacks.
src/canvas/core.py— model-independent parser-first-hit validation, log-space probability calculations, adaptive allocation, ratio correction, fallbacks, and the independent event-seed ledger.src/canvas/vhector_grammar.py— an incremental DFA logits processor for the vHector SVG token vocabulary.src/canvas/adapters/vhector.py— a thin, path-configurable adapter. The upstream vHector checkout is not copied into this repository.src/canvas/h1_runner.pyandscripts/h1_runner.py— batched vLLM H1 inference with resumable JSON receipts and arbitrary shard/GPU assignment.docs/reward_worker_protocol.md— the interface for a user-supplied renderer and bounded reward worker.configs/— placeholder examples only; no data or model files.
The core and parser utilities have no mandatory third-party dependency:
python -m venv .venv
. .venv/bin/activate
pip install -e ".[test]"For GPU inference, install the versions compatible with your CUDA and vLLM stack (the optional extra is a starting point, not a hardware-specific lock):
pip install -e ".[inference]"The runner was written for the vLLM API with engine-level logits processors. Check your installed vLLM release before a long run; the core tests remain CPU-only.
The task manifest is JSONL. Each non-empty line must contain an integer
index, a stable string id, and a text caption, for example:
{"index": 0, "id": "example-0000", "caption": "a simple red square"}You must supply, separately and under their own terms:
- a compatible local vHector checkpoint and tokenizer;
- the upstream vHector conversion module (set
VHECTOR_CODEor pass--upstream-code); and - a reward worker implementing the JSON-lines protocol in
docs/reward_worker_protocol.md.
The reward worker must return a finite bounded_score in [0, 1] for each
renderable SVG. Scores must be derived only from the supplied caption and SVG;
the worker must not load sample-specific references or labels.
From the repository root:
export VHECTOR_CODE=/path/to/upstream/vHector/code/vHector
python scripts/h1_runner.py \
--tasks /path/to/tasks.jsonl \
--model /path/to/local/checkpoint \
--output-root /path/to/output \
--reward-worker /path/to/reward_worker.py \
--scorer-config configs/scorer.example.json \
--physical-gpu 0--adapter and --grammar-module default to the bundled modules. Use
--num-shards N and --shard-index K to split a manifest across independent
processes. --resume is enabled by default; every run records its effective
configuration, source hashes, GPU receipt, event-seed ledger, per-stroke
receipts, and final JSONL manifest under --output-root.
The runner uses a fixed one-stroke future horizon (H1) and rejects other horizon values.
Candidate particles remain distinct even when their token blocks are equal.
All likelihood products and weights are accumulated in log space. Pilot
outcomes are not reused as fresh outcomes, and categorical selection is sampled
from the recorded distribution rather than taking an argmax. A malformed or
unrenderable hypothetical future receives the configured positive
--failure-epsilon mass and is retained in the audit trail.
Keep checkpoints, datasets, generated SVG/PNG files, logs, credentials, and cache directories outside Git.
Please cite the CANVAS paper and the upstream vHector work when using this
release. vLLM and Transformers are optional dependencies with their own
licenses. See THIRD_PARTY_NOTICES.md for the
boundary between original CANVAS code and external components.
Original CANVAS code in this repository is released under the MIT License. Third-party code, checkpoints, datasets, and evaluator assets are not relicensed by this notice; retain their upstream attribution and terms.