Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Redactor Onnx Laravel Package

kirschbaum-development/redactor-onnx

A Laravel package for redacting sensitive text using ONNX models, bringing local, privacy-friendly redaction to PHP apps so you can detect and mask data before storage or display.

View on GitHub
Deep Wiki
Context7

Getting Started

This release turns the redactor into a self-contained package: the new onnx driver runs a token-classification model inside the PHP process via TransformersPHP, so there is no sidecar service to deploy, network-hop to, or health-check.

  1. Install the runtime prerequisites first. TransformersPHP needs a PHP build with FFI enabled plus a platform ONNX Runtime binary. Verify before anything else:
    php -m | grep -i ffi
    composer require codewithkyrian/transformers
    
    On shared hosting or hardened images where ffi.enable is off, this driver will not work — plan for that early.
  2. Select the driver. Point the redactor's recogniser configuration at onnx (alongside your model id and the label→entity mapping) and keep the previous driver in config as a fallback until you have parity.
  3. Warm the model. Add php artisan redactor:onnx:warm to your deploy/build step so the first user request never pays the download-and-load cost:
    php artisan redactor:onnx:warm
    
  4. First use case: redact a structured payload (form submission, support ticket, log context array). Because the driver implements BatchRecognizer, the interesting move is passing the whole payload through once rather than looping field by field — every prose value is classified in a single model call.

Start in a queue job or an artisan command rather than a hot web endpoint, so you can measure latency and memory without user impact.

Implementation Patterns

Batch at the payload boundary, not the field boundary. BatchRecognizer is the reason to adopt this driver. Instead of:

foreach ($payload as $key => $value) {
    $payload[$key] = $redactor->redact($value); // N model calls
}

pass the payload and let the recogniser classify all prose values in one call. This is where the in-process driver wins over a sidecar: no per-value HTTP round trip, and the tokenizer batches across values.

Warm at build time, not boot time. Run redactor:onnx:warm in your Dockerfile or release script and keep the model cache directory on a persisted path (baked into the image, or a mounted volume). Warming in a service provider is a trap: every FPM worker pays it, and a cold container pays it per request.

Long-lived workers are your friend. Queue workers and Octane keep the model loaded across jobs, which amortises the load cost. Pair that with restarts on deploy so workers pick up a new model version.

Lean on the built-in windowing, but chunk deliberately where spans matter. Long texts are cut into windows at whitespace, which keeps you under token limits. For documents where redaction offsets are returned to a downstream consumer, pre-chunk on paragraph boundaries yourself so a span never straddles a cut.

Keep the label mapping in config, not code. Model labels are mapped to the entity names your profiles already use. Verify that mapping against your profiles explicitly — a renamed label that silently falls through to "unknown" means PII slips through unredacted while everything looks green.

Maintain driver parity in tests. Run the same fixtures through the sidecar and onnx drivers and diff the redacted output. This is the cheapest guard against a model swap quietly changing what gets redacted, and it makes the sidecar a genuine fallback rather than a dead config branch.

Isolate in a job for anything heavy. Redaction of a large payload is CPU-bound and single-threaded per process; a queued job with a timeout and a worker pool sized for memory (not just CPU) is the sane default.

Gotchas and Tips

  • FFI and the ONNX Runtime binary are hard requirements. Container base images and CI runners frequently ship without them. Test the warm command in the same image and as the same user that serves traffic — a warm cache written by root under a different HOME is invisible to www-data.
  • Memory multiplies per worker. An in-process model is loaded once per PHP process. Eight FPM workers means eight model copies. Either route redaction through a small dedicated worker pool or accept the RAM line item; check memory_limit against measured RSS, not the model file size alone.
  • First call is always slow. Download + load + first inference can be seconds. Assert in CI that a warm run is fast, and treat any cold-start latency regression as a deploy failure, not an observation.
  • Windowing can split an entity. A name cut across a window boundary may produce two partial detections or none. If you return redaction spans, check offsets at the seams; overlapping windows with de-duplication is the usual fix.
  • Label mismatch fails silently. The mapping is the whole contract between model and profiles. Log the set of labels the model actually emits at startup and diff it against the mapping — a warning at boot beats a leak in production.
  • Batch padding wastes compute. Batching many short values with one very long value inflates the call. Sort or group by length if payloads are heterogeneous and latency matters.
  • Never log the recogniser's output verbatim. Detected entity text is the PII you were asked to remove. Log entity types, counts, and durations only.
  • Extension point worth knowing: because the contract is BatchRecognizer, you can implement your own driver (regex for structured identifiers, a rules-based recogniser for account numbers) and compose it with the ONNX one — models are good at names and places, poor at checksummed formats. Run cheap deterministic recognisers first and send the model only what survives.
  • Version-pin the model. A model update changes redaction behaviour with no code diff. Pin the model id and revision in config, and re-run your parity fixtures when you bump it.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json
refinery29/php-cs-fixer-config
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules