Custom models¶
The integrated presets cover common workflows. For another model, create or
load it with your own library and supply an adapter that implements the small
NERAdapter contract. The adapter connects your model to the rules, line
router, calibration, and span merging.
Define an adapter¶
Implement training, prediction, and saving:
from collections.abc import Sequence
from pathlib import Path
from spacy.tokens import Doc
from pseudopath import EntityPrediction
class MyAdapter:
def fit(
self,
model: object,
train_docs: Sequence[Doc],
validation_docs: Sequence[Doc],
*,
training: object | None,
work_dir: Path,
) -> object:
# Train or update the supplied model and return it.
raise NotImplementedError
def predict(
self, model: object, texts: Sequence[str]
) -> Sequence[Sequence[EntityPrediction]]:
# Return predictions for the texts in the same order.
raise NotImplementedError
def to_disk(self, model: object, path: str | Path) -> None:
# Save the model under path.
raise NotImplementedError
PseudoPath.fit(training=...) passes the training settings to the adapter
as-is. work_dir is available for intermediate training files.
An adapter may update the supplied model in
place, but fit must return the model PseudoPath should use thereafter.
Leave the supplied documents’ gold annotations and patient context unchanged.
Retokenize into new documents when your model requires different tokens.
Training settings can be any object your adapter accepts. Record them in your
experiment history.
Prediction contract¶
EntityPrediction(start, end, label) uses a zero-based, half-open character
range [start, end) in each input text. The outer sequence returned by
predict must have the same length and order as texts. When routing is
active, a text can be a packed selection of physical lines rather than a
full document. Predictions that cross an inserted separator are discarded
during projection. Offsets must align with the output document’s EDS tokens
so PseudoPath can return spaCy spans. Unaligned predictions raise an error.
Train and save¶
Use your adapter with a model that you create externally:
from pseudopath import PseudoPath
model = load_my_model() # Load with your model library.
pipeline = PseudoPath(model=model, adapter=MyAdapter())
pipeline.fit(train_docs, validation_docs, training=my_settings)
pipeline.to_disk("pseudopath-artifact")
Here train_docs, validation_docs, and my_settings are your corpus and
model settings.
Restore a model¶
Supply the adapter and a callable that loads the saved model:
restored = PseudoPath.from_disk(
"pseudopath-artifact",
adapter=MyAdapter(),
model_loader=load_my_model_from_disk,
)
The loader receives the saved model subdirectory and returns a model object. It may capture device settings or other initialization parameters. Install your model library’s dependencies and record its checkpoint revision. When you save an instance loaded with this pair, supply the pair again to restore it, including instances originally created from a preset.
External EDS-NLP models, including EDS-Pseudo¶
EdsNLPAdapter accepts an EDS-NLP pipeline containing exactly normalizer
and ner, in that order, with one Transformer. The NER component must write
to doc.spans["pseudo-ml"], including an empty group when no entities are found
(use span_setter={"pseudo-ml": True}). A pipeline that only writes doc.ents
does not satisfy this contract. Prepare the neural-only pipeline yourself,
then use the existing adapter:
import edsnlp
from pseudopath import (
PATIENT_IDENTIFIER_LABELS, EdsNLPAdapter, PseudoPath, TransformerTraining, read_jsonl
)
model = edsnlp.load("/path/to/prepared/neural-only-pipeline")
pipeline = PseudoPath(model, adapter=EdsNLPAdapter(device="cpu"))
pipeline.fit(
read_jsonl("train.jsonl"),
read_jsonl("validation.jsonl"),
training=TransformerTraining(
max_length=256,
task_lr=1e-5,
transformer_lr=1e-6,
trainable_transformer_layers=1,
selection_labels=PATIENT_IDENTIFIER_LABELS,
),
)
For EDS-Pseudo, obtain checkpoint access and install its dependencies before
preparing the neural pipeline.
Do not pass its original rule and merge components: PseudoPath already applies
its fixed rules. A loaded NER head must support all training labels. Configure
Transformer window and stride on the model itself. See
architecture overrides.
A fresh compatible EDS-NLP head can infer labels on its first fit.
External spaCy models¶
Use SpacyNERAdapter for a compatible spaCy NER pipeline.
Select spacy.require_cpu() or
spacy.require_gpu(0) before construction or loading. The adapter does
not move the parser’s mixed CPU/GPU layers. Import edsnlp before loading
an EDS-language spaCy model so that its language and tokenizer are registered.