Views
No views yet
pritamdeka/S-BioBert-snli-multinli-stsb, a Sentence-Transformers model based on BioBERT.last_hidden_state. To reproduce the original Sentence-Transformers sentence embeddings, consumers must apply mean pooling using the attention mask, followed by optional L2 normalization when using cosine similarity.model.onnx: original ONNX export from the Sentence-Transformers Transformer module.model_optimized.onnx: ONNX Runtime optimized version for CPU inference.config.json: Transformer configuration.tokenizer.json: tokenizer file.tokenizer_config.json: tokenizer configuration.special_tokens_map.json: special tokens configuration.vocab.txt: BERT vocabulary.modules.json: Sentence-Transformers module definition.sentence_bert_config.json: Sentence-Transformers configuration.config_sentence_transformers.json: Sentence-Transformers metadata.1_Pooling/config.json: pooling configuration used by the original Sentence-Transformers model.README.md: this documentation.7681Vector size: 768
2Distance: Cosinepritamdeka/S-BioBert-snli-multinli-stsboptimum-cli export onnx path was not used because the Hugging Face Optimum exporter attempted to modify the SentenceTransformer.config property, which is not writable in the installed Sentence-Transformers version.1model = SentenceTransformer(
2 "pritamdeka/S-BioBert-snli-multinli-stsb",
3 device="cpu",
4)
5
6transformer = model[0].auto_model
7tokenizer = model[0].tokenizer1input_ids
2attention_mask
3token_type_idslast_hidden_state1cd /Users/filipelopes/Desktop/Development/convert-onnx
2python3 -m venv .venv
3source .venv/bin/activate
4
5pip install -U pip
6pip install -U torch transformers sentence-transformers "optimum[onnxruntime]" onnx onnxruntime onnxscript huggingface_hub1torch: 2.12.0
2transformers: 4.57.6
3sentence-transformers: 5.5.1
4onnx: 1.21.0
5onnxruntime: 1.26.0
6mps available: True1from pathlib import Path
2
3import torch
4from sentence_transformers import SentenceTransformer
5
6MODEL_ID = "pritamdeka/S-BioBert-snli-multinli-stsb"
7OUT_DIR = Path("./S-BioBert-snli-multinli-stsb-onnx")
8
9OUT_DIR.mkdir(parents=True, exist_ok=True)
10
11model = SentenceTransformer(MODEL_ID, device="cpu")
12model.eval()
13
14transformer = model[0].auto_model
15tokenizer = model[0].tokenizer
16
17transformer.to("cpu")
18transformer.eval()
19
20model.save(str(OUT_DIR))
21tokenizer.save_pretrained(OUT_DIR)
22transformer.config.save_pretrained(OUT_DIR)
23
24dummy = tokenizer(
25 ["Patient has chronic kidney disease."],
26 padding=True,
27 truncation=True,
28 max_length=128,
29 return_tensors="pt",
30)
31
32dummy = {k: v.to("cpu") for k, v in dummy.items()}
33
34input_names = ["input_ids", "attention_mask"]
35args = (dummy["input_ids"], dummy["attention_mask"])
36
37has_token_type_ids = "token_type_ids" in dummy
38
39if has_token_type_ids:
40 input_names.append("token_type_ids")
41 args = (
42 dummy["input_ids"],
43 dummy["attention_mask"],
44 dummy["token_type_ids"],
45 )
46
47
48class TransformerWrapper(torch.nn.Module):
49 def __init__(self, transformer, has_token_type_ids: bool):
50 super().__init__()
51 self.transformer = transformer
52 self.has_token_type_ids = has_token_type_ids
53
54 def forward(self, input_ids, attention_mask, token_type_ids=None):
55 if self.has_token_type_ids:
56 outputs = self.transformer(
57 input_ids=input_ids,
58 attention_mask=attention_mask,
59 token_type_ids=token_type_ids,
60 return_dict=True,
61 )
62 else:
63 outputs = self.transformer(
64 input_ids=input_ids,
65 attention_mask=attention_mask,
66 return_dict=True,
67 )
68
69 return outputs.last_hidden_state
70
71
72wrapper = TransformerWrapper(
73 transformer=transformer,
74 has_token_type_ids=has_token_type_ids,
75)
76
77wrapper.to("cpu")
78wrapper.eval()
79
80dynamic_axes = {
81 "input_ids": {0: "batch", 1: "sequence"},
82 "attention_mask": {0: "batch", 1: "sequence"},
83 "last_hidden_state": {0: "batch", 1: "sequence"},
84}
85
86if has_token_type_ids:
87 dynamic_axes["token_type_ids"] = {0: "batch", 1: "sequence"}
88
89with torch.no_grad():
90 torch.onnx.export(
91 wrapper,
92 args=args,
93 f=str(OUT_DIR / "model.onnx"),
94 input_names=input_names,
95 output_names=["last_hidden_state"],
96 dynamic_axes=dynamic_axes,
97 opset_version=17,
98 do_constant_folding=True,
99 dynamo=False,
100 )
101
102print("Exported to:", OUT_DIR / "model.onnx")
103print("Input names:", input_names)model.onnx411 MB1python -m onnxruntime.transformers.optimizer \
2 --input ./S-BioBert-snli-multinli-stsb-onnx/model.onnx \
3 --output ./S-BioBert-snli-multinli-stsb-onnx/model_optimized.onnx \
4 --model_type bert \
5 --num_heads 12 \
6 --hidden_size 768 \
7 --opt_level 21Use model_optimized.onnx by default for CPU inference.
2Keep model.onnx as the reference exported ONNX graph.1ST shape: (4, 768)
2ONNX shape: (4, 768)
3Cosine ST vs ONNX per row:
4[0.99999991 1.00000002 0.99999995 0.9999999]
5Mean cosine: 0.9999999446847581
6Max abs diff: 2.4854133212626195e-07pip install -U transformers onnxruntime huggingface_hub numpy1import numpy as np
2import onnxruntime as ort
3
4from huggingface_hub import hf_hub_download
5from transformers import AutoTokenizer
6
7repo_id = "filipelopesmedbr/S-BioBert-snli-multinli-stsb-onnx"
8
9tokenizer = AutoTokenizer.from_pretrained(repo_id)
10
11onnx_path = hf_hub_download(
12 repo_id=repo_id,
13 filename="model_optimized.onnx",
14)
15
16texts = [
17 "Patient has chronic kidney disease.",
18 "The patient was diagnosed with renal failure.",
19]
20
21encoded = tokenizer(
22 texts,
23 padding=True,
24 truncation=True,
25 max_length=512,
26 return_tensors="np",
27)
28
29session = ort.InferenceSession(
30 onnx_path,
31 providers=["CPUExecutionProvider"],
32)
33
34inputs = {
35 "input_ids": encoded["input_ids"],
36 "attention_mask": encoded["attention_mask"],
37}
38
39if "token_type_ids" in encoded:
40 inputs["token_type_ids"] = encoded["token_type_ids"]
41
42outputs = session.run(None, inputs)
43
44token_embeddings = outputs[0]
45attention_mask = encoded["attention_mask"]
46
47mask = np.expand_dims(attention_mask, axis=-1)
48
49embeddings = np.sum(token_embeddings * mask, axis=1) / np.clip(
50 np.sum(mask, axis=1),
51 a_min=1e-9,
52 a_max=None,
53)
54
55embeddings = embeddings / np.linalg.norm(
56 embeddings,
57 axis=1,
58 keepdims=True,
59)
60
61print(embeddings.shape)
62print(embeddings[0][:10])(2, 768)1mask = np.expand_dims(attention_mask, axis=-1)
2
3embeddings = np.sum(token_embeddings * mask, axis=1) / np.clip(
4 np.sum(mask, axis=1),
5 a_min=1e-9,
6 a_max=None,
7)1embeddings = embeddings / np.linalg.norm(
2 embeddings,
3 axis=1,
4 keepdims=True,
5)1hf auth login
2
3hf upload \
4 filipelopesmedbr/S-BioBert-snli-multinli-stsb-onnx \
5 ./S-BioBert-snli-multinli-stsb-onnx \
6 . \
7 --repo-type model \
8 --commit-message "Add ONNX export"1hf upload \
2 filipelopesmedbr/S-BioBert-snli-multinli-stsb-onnx \
3 ./S-BioBert-snli-multinli-stsb-onnx/model_optimized.onnx \
4 model_optimized.onnx \
5 --repo-type model \
6 --commit-message "Add optimized ONNX model"1hf upload \
2 filipelopesmedbr/S-BioBert-snli-multinli-stsb-onnx \
3 ./S-BioBert-snli-multinli-stsb-onnx/README.md \
4 README.md \
5 --repo-type model \
6 --commit-message "Add README documenting ONNX export process"model_optimized.onnx is recommended for CPU inference.model.onnx is kept as the reference ONNX export.SentenceTransformer.encode().pritamdeka/S-BioBert-snli-multinli-stsb