feat: add worker-backed PII local models#558
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Production-oriented Rampart benchmark rerun on Environment
Hot-path results These are two full repeated runs with
The realistic mixed distribution was 50% 128 B, 35% 1 KiB, and 15% 8 KiB:
Throughput stays flat while queueing latency grows, which matches the intentionally serialized detector. This is suitable for small, explicitly selected content fields; it is not a good fit for indiscriminately scanning large event bodies. Managed LLM request+response sanitization ran 30/30 calls successfully at 19.66 ms p50 / 20.05 ms p95. Every captured event was redacted, the caller-visible response value was preserved, and unselected metadata remained untouched. Memory and tuning The current default
Batch size 1 used much less memory and was slightly faster. With that setting, combined host+worker RSS was 184 MiB after activation and 269–271 MiB after the full workload. Two separate 2,000-call soaks added only 0.49–0.67 MiB, so this looks like ONNX arena sizing by batch rather than an unbounded per-request leak. Cached worker activation was roughly 0.33–0.41 s; teardown p50 was 4.48 ms. The first managed-environment install worked through the normal plugin lifecycle, but required a locally built Failure behavior
Detection-quality probe This was a small adversarial smoke corpus, not a model-quality benchmark:
The practical boundary remains important: keep the ML provider on explicit content paths and retain deterministic recognizers for structured identifiers. The end-to-end run confirmed that technical metadata such as region and trace ID stayed outside the selected paths. Readout The worker/plugin architecture and failure isolation hold up under load. I would change the default inference batch to 1 before treating this as production-ready, document the serialized-throughput and language limits, and tune the score against a representative product corpus. No benchmark code or result artifacts were added to the repository. |
Signed-off-by: Alex Fournier <afournier@nvidia.com>
Signed-off-by: Alex Fournier <afournier@nvidia.com>
Signed-off-by: Alex Fournier <afournier@nvidia.com>
Signed-off-by: Alex Fournier <afournier@nvidia.com>
Signed-off-by: Alex Fournier <afournier@nvidia.com>
Signed-off-by: Alex Fournier <afournier@nvidia.com>
Signed-off-by: Alex Fournier <afournier@nvidia.com>
b73ac66 to
385c241
Compare
Overview
Add an implementation-language-neutral inference-provider surface to
grpc-v1workers and use it to back the existing PII redaction
local_modellane. Thefirst optional provider integrates Rampart as an isolated Python worker without
adding ONNX, tokenizer, or model-download dependencies to the Relay host.
Details
and expose provider registration through the Rust and Python worker SDKs.
Providers are installed before plugin components and deregistered before
worker shutdown.
compiled JSON paths, payload batching, limits, deadlines, detection
validation, deterministic composition, replacement, and fail-closed behavior
remain host-owned.
preserving explicit raw target paths for no-codec calls and omitting unsafe
event payloads when codec decoding fails.
local_modelconfiguration parity for Rust, Python, Node.js,and Go consumers.
checksum-verified during an explicit prefetch step; activation is offline,
and model weights are not bundled.
inference, and send all selected fields through one bounded provider call.
malformed-detection, codec, raw-payload, binding, and real-worker end-to-end
coverage. Update worker and PII documentation.
or CI workflow changes are included.
This is additive. Rampart remains optional and disabled by default. It is one
contextual detection lane intended to be composed with deterministic
recognizers, not a standalone privacy guarantee.
Validation completed:
uv run pre-commit run --all-filesjust test-rust(all PII, core, worker, and completed workspace suites passed; one unrelated CLI path assertion is incompatible with this worktree's symlinked shared target directory)just test-python(557 passed)just test-python-plugin(125 passed plus real worker E2E)just test-node(291 passed)just test-gocargo test -p nemo-relay-pii-redaction(132 unit and 2 integration tests passed)cargo test -p nemo-relay --features worker-grpc --test worker_plugin_integration(33 passed)just docsjust docs-linkcheckcargo fmt --all -- --checkgit diff --checkLocal exploratory evaluation on Apple Silicon, using the real manifest-backed
worker and composed deterministic-email plus Rampart profiles:
Cached model initialization was approximately 36 ms with approximately
49.8 MiB additional resident memory. A 64-call concurrent short-input run
completed in 35.97 ms. Longer synthetic samples exposed contextual-name false
negatives, and broad scans produced false positives on some region, UUID, and
trace-like values. Those findings are why the documented configuration composes
the model with deterministic recognizers and restricts selected content fields.
Where should the reviewer start?
Start with
crates/core/src/plugin/inference.rsandcrates/core/src/plugin/dynamic/worker.rsfor provider ownership, contractvalidation, and teardown. Then review
crates/pii-redaction/src/local.rsforthe host-owned policy, batching, and codec behavior.
crates/pii-redaction/tests/worker_provider_tests.rsexercises the completeworker-backed path. The optional Rampart provider is under
crates/pii-redaction/providers/rampart/.Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)