OpenMed models download once from the Hugging Face Hub into a local cache, then run fully on-device — no network, no telemetry. This skill covers how to load a model, reuse it across many calls without reloading weights, point at a local copy, and run offline.
cache_dir) or force CPU/GPU.For which model to load, see choosing-openmed-models. To actually run it, see
extracting-clinical-entities.
pip install "openmed[hf]" # adds Hugging Face transformers + hub download
analyze_text, extract_pii, load_model, and ModelLoader.load_model all
accept the same model_name in three forms:
| Form | Example | Notes |
|---|---|---|
| Registry key | "disease_detection_superclinical" |
Short, resolved via the bundled registry. |
| Full HF id | "OpenMed/OpenMed-NER-DiseaseDetect-BigMed-278M" |
Anything org/name; downloaded from the Hub. |
| Local path | "/models/my-openmed-ner" |
An existing directory; loaded with local_files_only=True. |
A bare name without / is prefixed with the default org (OpenMed). An existing
local path is detected automatically and never hits the network.
The single most important pattern — build one ModelLoader, pass it everywhere.
The loader caches models, tokenizers, and pipelines in memory, so the second call
is instant.
import openmed
from openmed import ModelLoader, OpenMedConfig
# One loader, reused across calls. Weights load on the first call only.
loader = ModelLoader()
notes = [
"Patient prescribed 500 mg metformin for type 2 diabetes.",
"History of myocardial infarction; started on atorvastatin.",
]
for note in notes:
result = openmed.analyze_text(
note,
model_name="disease_detection_superclinical",
loader=loader, # <-- reuse; no reload on subsequent calls
output_format="dict",
)
print(result.entities)
Without loader=, each analyze_text call constructs a fresh ModelLoader. The
underlying Hugging Face cache still prevents re-downloads, but you pay to
re-instantiate the pipeline — avoid that in loops and services.
When you want the raw model/tokenizer (e.g. to inspect config or build a custom pipeline):
from openmed import load_model
bundle = load_model("disease_detection_superclinical")
model = bundle["model"]
tokenizer = bundle["tokenizer"]
config = bundle["config"]
load_model(model_name, config=None, **kwargs) is a thin convenience wrapper that
builds a ModelLoader and calls loader.load_model(...). For reuse, prefer
constructing the loader yourself:
loader = ModelLoader()
bundle = loader.load_model("disease_detection_superclinical")
# Second call returns the cached bundle (no reload):
bundle2 = loader.load_model("disease_detection_superclinical")
# Force a fresh load if you replaced files on disk:
fresh = loader.load_model("disease_detection_superclinical", force_reload=True)
OpenMedConfig is a dataclass. Pass it to ModelLoader(config=...).
from openmed import ModelLoader, OpenMedConfig
config = OpenMedConfig(
cache_dir="/data/openmed-cache", # default: ~/.cache/openmed
device="cpu", # None = auto-detect
default_org="OpenMed", # prepended to bare model names
hf_token=None, # or set env HF_TOKEN for private repos
)
loader = ModelLoader(config)
Relevant OpenMedConfig fields: cache_dir, device, default_org, hf_token,
timeout (default 300s), backend (None auto / "hf" / "mlx"), log_level.
hf_token falls back to the HF_TOKEN environment variable.
cache_dir.To guarantee no network access (air-gapped, CI, PHI environments), set the standard Hugging Face offline switch before importing:
export HF_HUB_OFFLINE=1
export TRANSFORMERS_OFFLINE=1
Or vendor the model and pass a local path — that path is loaded with
local_files_only=True and never contacts the Hub:
result = openmed.analyze_text(note, model_name="/models/openmed-disease-ner")
To pre-warm a cache for offline use, run one inference (or load_model) once with
network access, then disable it.
Useful before chunking long documents:
from openmed import get_model_max_length, ModelLoader
loader = ModelLoader()
max_len = get_model_max_length("disease_detection_superclinical", loader=loader)
print(max_len) # e.g. 512 — None if it can't be inferred
get_model_max_length(model_name, *, config=None, loader=None) delegates to
loader.get_max_sequence_length(model_name). Pass the same loader you use for
inference so the tokenizer is loaded only once.
The loader holds models in RAM until released:
loader.unload_model("disease_detection_superclinical") # drop one model
loader.unload_all_models() # drop everything
loader.loaded_models() # inspect what's cached
choosing-openmed-models: that skill yields a model key or HF id; feed
it straight into ModelLoader.load_model(...) or as model_name=.extracting-clinical-entities: pass your reused loader= into
openmed.analyze_text(...) so a long batch loads weights exactly once.openmed.extract_pii(..., loader=loader) and
openmed.deidentify(..., loader=loader) accept the same loader — share one
loader across NER and PHI steps in a pipeline.loader = ModelLoader(OpenMedConfig(cache_dir="/data/openmed-cache"))
phi = openmed.deidentify(note, method="mask", loader=loader)
ner = openmed.analyze_text(phi.deidentified_text, loader=loader)
pip install openmed alone is not enough to download models — add the
[hf] extra (or have transformers + huggingface_hub installed). ModelLoader
raises ImportError with an install hint if transformers is missing.force_reload=True is required after you overwrite files in a local model
directory; otherwise the in-memory cache is served.hf_token (or HF_TOKEN) and HF_HUB_OFFLINE unset for
the first download.cache_dir should not live inside a PHI data directory.