A local model directory turns a trained Sentence Transformers model into an artifact that another process can load without the original Python object. The directory carries the transformer, tokenizer, pooling configuration, and model metadata needed to reproduce the same embedding behavior.
The SentenceTransformer.save_pretrained() method writes the complete model layout and uses .safetensors weights by default. Passing that directory to a new SentenceTransformer() instance restores the modules described by modules.json, while local_files_only=True prevents the reload from retrieving missing files from the Hugging Face Hub.
The comparison uses the same two texts before and after the handoff. Matching shapes and numerically equal embeddings prove that the saved directory can replace the in-memory source model for later inference.
Steps to save and reload a Sentence Transformers model:
- Create save_reload.py with the source model ID, saved-model path, and comparison texts.
- save_reload.py
from pathlib import Path import numpy as np from sentence_transformers import SentenceTransformer model_id = "sentence-transformers/all-MiniLM-L6-v2" save_path = Path("models/support-embeddings") texts = [ "reset a forgotten password", "send a password recovery email", ]
A new model artifact needs an empty path so files from an older export cannot remain beside the new weights and configuration.
- Add the source-model encoding block beneath the texts list.
source_model = SentenceTransformer(model_id) before = source_model.encode(texts, show_progress_bar=False)
- Add the save and local-only reload block beneath the source encoding.
source_model.save_pretrained( str(save_path), safe_serialization=True, ) reloaded_model = SentenceTransformer( str(save_path), local_files_only=True, ) after = reloaded_model.encode( texts, show_progress_bar=False, )
safe_serialization=True writes .safetensors weights. local_files_only=True makes an incomplete local export fail instead of silently downloading a missing component.
- Add the embedding comparison and result output beneath the reloaded encoding.
max_abs_diff = float(np.max(np.abs(before - after))) if before.shape != after.shape: raise SystemExit("embedding shape changed after reload") if not np.allclose( before, after, rtol=1e-5, atol=1e-6, ): raise SystemExit("embedding values changed after reload") print(f"saved model: {save_path}") print("local-only reload: passed") print(f"embedding shape: {after.shape}") print(f"max absolute difference: {max_abs_diff:.8f}")
The comparison can fail on either a changed embedding shape or values outside the stated floating-point tolerance, so a printed pass is tied to the reloaded model's actual output.
- Run save_reload.py to verify that the saved model reloads locally with matching embeddings.
$ python save_reload.py saved model: models/support-embeddings local-only reload: passed embedding shape: (2, 384) max absolute difference: 0.00000000
The models/support-embeddings directory remains the reusable model artifact. The first line identifies the directory that a later process should pass to SentenceTransformer().
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.