Skip to main content

MedDeID

MedDeID is a local-first, multilingual framework for clinical text de-identification. It provides a Python API, command-line interface, batch processor, and optional FastAPI service for compatible model bundles and locale-specific language profiles. Public models support Dutch and English; data generation, training, evaluation, and annotation packages are not required for inference.

For cross-suite navigation and task-oriented guidance, see the MedDeID website and documentation. This repository remains authoritative for inference APIs, CLI options, service settings, and deployment.

Language support

Language Language profiles Public model
Dutch nl-BE in the current public bundle stighellemans/meddeid-dutch-synth
English en-GB, en-US stighellemans/meddeid-english-synth
Additional languages Pluggable Requires a compatible model bundle and language profile

Model bundles pin their supported profiles. MedDeID selects a regional profile explicitly and never guesses between locales such as British and US English.

Easiest start: Python CLI

For the shortest first run, install the released package and use the CLI. This does not require writing Python code or installing Docker:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install meddeid
meddeid models
meddeid deidentify note.txt \
  --model stighellemans/meddeid-dutch-synth

For a quick synthetic example, pass literal text explicitly:

meddeid deidentify --text "mijn naam is Noor Janssens" \
  --model stighellemans/meddeid-dutch-synth

Literal text is visible in shell history and may briefly be visible in the process list, so prefer an input file for patient data.

meddeid models ends by stating where to use the selected model ID.

Try MedDeID in your browser

Install and start Docker Desktop, then clone this repository once:

git clone https://github.com/stighellemans/meddeid.git
cd meddeid

Choose Dutch:

./scripts/start-local.sh \
  --model stighellemans/meddeid-dutch-synth \
  --language-profile nl-BE

Or choose English:

./scripts/start-local.sh \
  --model stighellemans/meddeid-english-synth \
  --language-profile en-GB

The browser opens with the API key already filled in. Paste a note and select De-identify. Stop MedDeID with ./scripts/stop-local.sh.

Developers testing source changes can add --build. For a shared service, see Production deployment.

Python HTTP service

Add the HTTP dependencies when another application needs the service or when deploying MedDeID as an HTTP service in a production environment:

python -m pip install 'meddeid[server]'

This installs the service runtime, not the surrounding production controls. See Production deployment for authentication, TLS, network, resource, monitoring, and validation requirements, and Inference and deployment for the availability matrix.

For dataset review, benchmarking, evaluation, training, synthetic-data, and contributor workflows, install the suite front door with the matching extras:

python -m pip install 'meddeid[research]'
# Language/profile and model-bundle contributors:
python -m pip install 'meddeid[contributor]'

Guided suite workflows

Use one entry point when you know the outcome but do not yet know which suite components or optional stages apply:

meddeid start
meddeid status ./my-workflow
meddeid next ./my-workflow

start first groups the suite into six familiar goals: de-identify text, prepare data, train, evaluate, deploy, or contribute. A second menu appears only when that goal has several possible workflows. Choices are numbered and ? explains why a scientific decision is being requested. next runs exactly one eligible stage and stops instead of guessing an unanswered branch. Hardware, browser runtime, and other operational choices are requested only when needed.

Run status or next without a path from anywhere inside the workflow directory. Add --details for every technical stage and exclusion reason.

Every workspace contains a checksummed meddeid.workflow.v1 manifest. Inspect the rationale and the underlying component command at any time:

meddeid status ./my-workflow --details
meddeid workflow explain ./my-benchmark
meddeid workflow run ./my-benchmark score --dry-run

The existing meddeid workflow ... commands remain the advanced and automation interface. Changing a scientific decision after work begins shows which stages become invalid and requires configure --yes before outputs are archived.

Quick start

First review the available public baselines and their validation scope:

meddeid models

Then select the model explicitly. MedDeID does not silently choose Dutch or a synthetic baseline for you:

meddeid deidentify note.txt \
  --model stighellemans/meddeid-dutch-synth
from meddeid import Deidentifier

deid = Deidentifier.from_pretrained("stighellemans/meddeid-dutch-synth")
result = deid("Patiënt Alex Voorbeeld kwam op controle.")
print(result.deid_text)
deid.close()

Use the public English model by selecting its regional profile:

meddeid deidentify note.txt \
  --model stighellemans/meddeid-english-synth \
  --language-profile en-GB

Dates use placeholders unless the caller explicitly supplies metadata.date_shift_days. A nonzero shift produces deterministic shifted dates; zero produces placeholders and a structured warning. One declarative age-granularity JSON policy is loaded for the complete engine, independent of the selected language profile.

The self-contained model bundle is downloaded and cached on first use. Document text is processed locally and is not sent to Hugging Face. Quickly inspect the resolved model, immutable revision, language profiles, files, and package versions with:

meddeid model-info --model stighellemans/meddeid-dutch-synth

The default inspection does not load the model weights into an inference runtime. Use --verify-runtime when an administrator also needs to verify that the configured backend and device can initialize:

meddeid model-info \
  --model stighellemans/meddeid-dutch-synth \
  --verify-runtime

model-info is read-only and does not set a persistent default. Each inference command still names its model explicitly. It is also the detailed local administrator view: model/cache paths, file inventory, and complete package versions are reported, so saved output should be treated as operationally sensitive. runtime.checked distinguishes inspection from runtime verification. When no revision is supplied, the command reports requested_revision: "latest" together with the immutable resolved_revision that was resolved.

CLI JSON and HTTP results remain flat and use the logical order deid_text, spans, processing, warnings, provenance. The nested provenance field contains only the MedDeID version, model identity, and selected language profile. Runtime, dependencies, cache details, and filesystem paths stay in model-info and batch manifests. Clinical text is not sent to Hugging Face.

For offline or air-gapped use, download an immutable snapshot in advance:

hf download stighellemans/meddeid-dutch-synth \
  --revision <immutable-hub-sha> \
  --local-dir ./meddeid-dutch-synth
meddeid deidentify note.txt --model ./meddeid-dutch-synth

Use revision= in Python or --revision on the CLI to pin reproducible deployments.

Batch inference

Canonical MedDeID JSONL can be processed directly. The batch command preserves document IDs and order, supports interruption-safe resume, and writes a sidecar manifest with input, output, model, profile, runtime, and timing metadata. Existing output is never overwritten implicitly.

meddeid batch project/splits/test.jsonl \
  --output predictions.jsonl \
  --model stighellemans/meddeid-dutch-synth

The input path may instead be written explicitly as meddeid batch --input project/splits/test.jsonl .... Both forms are equivalent for batch and deidentify; do not supply both in one command. For single-note inference, deidentify also accepts --text <text> instead of a file. Do not combine --text with either file-input form. MedDeID checks that the input is a readable file before resolving or loading the model, so path mistakes fail immediately.

The model is downloaded once and reused from the Hugging Face cache. Each online run checks whether the selected Hub revision changed; use --offline to prohibit that check. Automatic device selection prefers CUDA, then Apple MPS, and falls back to CPU. Use --device to override that order. Native MPS on the measured M4 Pro preserved semantics over all 300 public fixture notes and ran 1.6--2.0 times faster than native CPU across interactive, ETL, and long-note workloads. It is a native Python path rather than a container image.

HTTP service

PyTorch inference works on CPU, Apple MPS, and CUDA:

MEDDEID_MODEL=stighellemans/meddeid-dutch-synth \
MEDDEID_DEVICE=cpu \
meddeid-server

Multi-profile services can set a locale fallback once while still allowing trusted metadata.lang on a request to override it:

MEDDEID_MODEL=stighellemans/meddeid-english-synth \
MEDDEID_LANGUAGE_PROFILE=en-GB \
meddeid-server

The bundle declares its post-processing locales; users choose only the locale. The browser UI shows the active model and profile, and enables profile selection when the model supports more than one.

For an authenticated service:

export MEDDEID_MODEL=stighellemans/meddeid-dutch-synth
export MEDDEID_API_KEY='<random secret>'
export MEDDEID_REQUIRE_API_KEY=true
meddeid-server

For a reproducible direct installation, keep the non-secret settings in the provided environment-file template. Edit the copied file to select the model, profile policy, and API-key handling, then run:

cp server.env.example meddeid-server.env
chmod 600 meddeid-server.env
meddeid-server --env-file meddeid-server.env

Unknown and duplicate settings are rejected. Existing process environment variables take precedence, so a service manager can inject MEDDEID_API_KEY without storing it in the file. Docker Compose continues to use .env or docker compose --env-file <path>.

The service provides:

  • POST /deidentify for one document;
  • POST /deidentify-batch for throughput-oriented batches; and
  • GET /health for minimal readiness and enabled model/profile information.

For a shared service, choose CPU for the simplest portable deployment, PyTorch CUDA when the NVIDIA GPU may vary, or TensorRT with a target-specific compiled plan for a fixed, optimized GPU target. Native Apple MPS is also available through the Python installation. All paths retain the same API, tokenization, decoding, and locale-selected post-processing contract. The CPU and CUDA images contain no model weights: select a model in the environment file and the service caches it on first startup. The PyTorch CUDA image runs with:

docker compose \
  --env-file .env.cuda \
  -f compose.yaml \
  -f compose.cuda.yaml \
  up --detach meddeid

TensorRT is optimized for a supported GPU family and exact model revision. Its runtime and API gateway are weight-free, while the compiled model repository is supplied separately. This release provides separate Dutch and English plans for NVIDIA T4 and for Ampere-or-newer GPUs. Select the model, revision, and language profile in .env.triton; MedDeID detects the GPU and Compose downloads and verifies the matching plan. Choose CUDA instead when the GPU or model must change without a matching compiled plan. For another optimized target, contact stig.hellemans@uantwerpen.be without sending sensitive data.

Use /deidentify for individual notes and /deidentify-batch for planned batches. If interactive traffic and large batch jobs run simultaneously, operate separate service instances so batch work cannot delay interactive requests.

See the reader-focused production deployment guide for setup. Benchmark evidence and advanced tuning remain in the technical production reference, CUDA guide, and TensorRT guide.

Language profiles and metadata

The current public Dutch model bundle declares nl-BE. The Dutch language package also provides nl-NL, but it can only be selected when a compatible model bundle declares that profile. The public English model bundle supports both en-GB and en-US; metadata.lang or --language-profile selects the regional resources and post-processing. Bare en is rejected because it does not choose a regional profile.

Model bundles pin installed profiles provided through meddeid.language_profiles entry points, with no source-tree fallback. For a multi-profile bundle, document metadata is used first, followed by an explicit load-time default and then a single-profile bundle default; MedDeID never guesses between multiple profiles. Additional languages require a compatible model bundle and language profile. See Language profile selection.

Optional trusted metadata can recover known patient or caregiver names and birth-date representations or other known values after neural inference. Metadata is not concatenated to the note or sent to the model as an input feature. Incorrect metadata can create false-positive redactions, so callers must validate it.

Belgian DEDUCE is an independent comparison system and is not installed by this package.

Privacy and limitations

Local processing reduces data movement but does not guarantee anonymity. Validate the model on representative data from the intended setting, monitor both missed PII and unnecessary redaction, and use human review where errors can create material privacy risk. Secure cached models, inputs, outputs, manifests, and service logs according to your organization’s requirements.

Development

python -m pip install \
  -e ../meddeid-core \
  -e ../meddeid-language-nl \
  -e '.[dev]'
pytest

Licence

AGPL-3.0-only with the MedDeID Private Fine-Tuning Exception, version 1.0. The Exception permits private training data and resulting private fine-tuned weights to remain confidential; MedDeID code modifications remain subject to AGPL-3.0-only. See NOTICE and MEDDEID-PRIVATE-FINE-TUNING-EXCEPTION-1.0.txt. Model weights are distributed separately under the terms stated in their model card.

Metadata

Release files for meddeid 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for meddeid 0.4.1
File Size Uploaded
meddeid-0.4.1.tar.gz 169.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for meddeid 0.4.1
File Interpreter ABI Platform
meddeid-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 304.9 kB

Release files / meddeid-0.4.1.tar.gz

Download URL meddeid-0.4.1.tar.gz
Size 169.6 kB
Tags Source
SHA-256 checksum
How to use checksums
edcb8393c4e926c1506e4163bba04e8eabb7851f0182803a87f9e3d5cca38ffb
BLAKE2b-256 checksum
How to use checksums
c0ae40ea25ddf141448a853e29232cec84e0d88a99350828da39565115d72303
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / meddeid-0.4.1-py3-none-any.whl

Download URL meddeid-0.4.1-py3-none-any.whl
Size 135.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
39d3bde903271a737f90d9d9c4f5ef4c5d0a23179d3389fb9a03aab51b29d7ea
BLAKE2b-256 checksum
How to use checksums
96016710966537ddecb34f8dcf2820aa6343e2384155f6676702e8365d2c4273
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.2

2 release files

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page