惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
腾讯CDC
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
S
Schneier on Security
NISL@THU
NISL@THU
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Proofpoint News Feed
T
Threatpost
Scott Helme
Scott Helme
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
I
Intezer
C
Check Point Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cyber Attacks, Cyber Crime and Cyber Security
S
Securelist
Security Latest
Security Latest
大猫的无限游戏
大猫的无限游戏
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
云风的 BLOG
云风的 BLOG
量子位
T
Tor Project blog
博客园 - 叶小钗
The Cloudflare Blog
Simon Willison's Weblog
Simon Willison's Weblog
T
Tailwind CSS Blog
W
WeLiveSecurity
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
S
Security Affairs
罗磊的独立博客
Know Your Adversary
Know Your Adversary
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
Help Net Security
Help Net Security
美团技术团队
P
Privacy International News Feed
The Hacker News
The Hacker News
Hugging Face - Blog
Hugging Face - Blog
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

Towards AI

Building AI Agents in Rust — part 4 | Towards AI Building AI Agents in Rust — part 5 | Towards AI The Verified Identity Agent Bridge | Towards AI You Can’t Prompt Your Away Your LLM Problems | Towards AI The Free Agent Trap | Towards AI Your Agentic Loop Will Drift. Here Is the KL Divergence Equation That Measures How Far It Has Wandered From Its Original Instruction. | Towards AI Beyond Chat: Processing Images, PDFs, and Documents with the OpenAI Adapter in Oracle Integration Cloud | Towards AI Building AI Agents in Rust — part 3 | Towards AI Self-Hosting Airflow at Home: Automating Stock Price Data Collection | Towards AI The 76-Hour Frontier: How the Takedown of Claude Fable 5 Birthed the Military-Industrial-AI Complex | Towards AI I Trained a Markdown File to Boost GPT-5.5 by 23 Points — It Shouldn't Work | Towards AI We Replaced ChatGPT With a Local AI Server. Six Months of Honest Data. | Towards AI What Really Makes Cars Pollute? A Data Science Deep Dive into CO₂ Emissions | Towards AI Training GPT-2 From Scratch on a GTX1050 | Towards AI Principal Component Analysis (PCA): Theory, Mathematics, and Applications Build a Zero-Cost Web Automation Pipeline With OpenRouter, OpenClaw, and MediaUse I Gave Qwen3.7-Plus a Screenshot and It Found the Exact Pixel to Click for $0.40 Beyond the Prompt: Why Autonomous AI Agents Are Replacing the Chatbot Moonshot Cracked Claude Code’s Playbook with an MIT Terminal Agent and a $0.60 Model Connections, Roles, and Warehouses: Getting CoCo Desktop Production-Ready from Day One My First $5,000 Month Writing About AI Engineering on Medium Google Shrank Gemma 4 by 72% and Unsloth Fixed the 4-Bit Bug Nobody Else Caught on One 4090, and 4-Bit Shouldn’t Be This Good LangChain Explained: Understanding Models, Prompts, Chains, Memory, Indexes, and Agents TOON: Beyond JSON for LLMs Claude Code Casual, Pro, Elite: The Three Working Personas of Claude Code Mastery MiniMax M3 Decodes 1M Tokens 15x Faster — and It Shouldn’t Be This Cheap Using Amazon SQS for AI Agent Orchestration I Ran a 1.5B-Active Model on My Laptop That Embarrassed a 26B by 46 Points How to Build a Self-Improving Company with AI Part 3 — Implementation/Engine-Level: Choosing the Runtime That Gives You These for Free Part 2 — Serve-Level Speed: System Design That Stabilizes P95/P99 3-Part Series: LLM Latency in Production (Part 1) Claude Code: The AI Coding Partner Changing How Developers Build Software Claude Code Pitfalls: Claude Code Won’t Do What You Told It: A Troubleshooting Catalog Full-Stack Data Scientists for the Agentic Coding World Building Production-Grade AI Skills with Snowflake Cortex AI Function Studio I Tried 10 AI Agent Frameworks in 2026 — Here’s the Honest Guide I Wish I Had Earlier How One Spring Boot Optimization Saved Our Startup $30,000 a Year Inside Palantir AIP: How the World’s Most Controversial AI Platform Actually Works What Is a Reverse Proxy? (And Why Every Backend Developer Should Care) What Claude Opus 4.8 Actually Changes If You’re Building Agents QWEN 3.7 Max Worked For 35 Hrs Straight And The Results Were Mind-blowing When LLMs Meet Knowledge Graphs on the Battlefield Fine-Tuning is Dead: Why Context Orchestration Won in 2026 5 Things Broke When I Shipped a RAG + MCP Agent to Production. Google Co-Scientist: Hyper Scaling Research and Discovery Microsoft Just Embarrassed Browser Web Agents — 1,000 Lines Made GPT-5.4 Beat Opus 4.6 on 200 Web Tasks The Modern Data Stack Is Broken — Here’s How to Fix It With AI, Governance, and Real Architecture Building Production MCP Servers: What the Spec Won’t Tell You When Should an Agent Stop? The Anatomy of Termination Harness Engineering: The Layer That Matters More Than the Model AI Engineers Who Can’t Debug Are Getting Fired (Here’s How I Debug with Claude Code) Claude Code Memory: Why You Keep Explaining the Same Thing to Claude (and the Five Layers That Fix It) Claude Code Subagents: The Claude Code Feature You Skip Every Day (And Why It Quietly Wrecks Your Sessions) Agentic AI and the SMB Banking Advantage Claude Code: Spec-Driven Development — Why Your AI Coding Sessions Fall Apart at Hour Three The Real Cost of Agentic AI Nobody Budgets For SVM : 40 must visit Interview Questions (Part 2) Your AI Agent Works Perfectly in the Demo. Here Are the 6 Ways It Dies in Production. Terraform vs CI/CD for Serverless Deployments Merve Noyan Stopped Writing Training Scripts — Her Agent Just Fine-Tuned 18 Models Solo for $11.40 Why Your Sales Forecast Is Always 20% Wrong (And How To Make It 12% Wrong) Genetic Cubic n{C/A} Ratios For Elementary Robotics Design Top 20 AdaBoost Interview Questions & Answers (Part 2 of 2) Agentic AI Vs AI Agents — What Are the Key Differences? LAI #127: The Infrastructure Layer of AI Is Becoming the Product Anthropic Caught Its Own AI Planning to Blackmail Engineers RNNs Cannot Think What Transformers Think Cheaply. ICLR 2026 Proved the Gap Is Exponential. Time Series Made So Easy My Aunt Got It on the Second Read Claude Cowork 101 | Towards AI Is 3-Bit KV Cache the Holy Grail? A Reality Check on Google’s TurboQuant LangGraph Multi-Agent Architecture: Building a Self-Critiquing AI Debate System AutoML on Autopilot | Towards AI I Ran This Open-Source AI Tool on a Messy Codebase and Got 71x Fewer Tokens — Here Is Exactly What Happened Month in 4 Papers (April 2026) AI Kept Forgetting My Notes. Fixing That Taught Me How It Actually Works. How ChatGPT Makes You Addicted Crack ML Interviews with Confidence: K-Nearest Neighbors (KNN 20 Q&A) The Event-Driven Blueprint: How I Scaled a Spring Boot System to 10 Million Kafka Messages/Day Building Vector Search? Why FAISS Alone Isn’t Enough TAI #202: GPT-5.5 Moves Codex Into Real Work Machine Learning System Design -The Model Serving Triangle, With One Forward Pass Flowing Through Every Trade-off (Part3) AI Orchestration in Action: How MuleSoft and LLMs Fuel the Future of Enterprise AI GPT-4 Has 1.8 Trillion Parameters. It Uses 2% of Them Per Token. Part 20: Data Manipulation in Multi-Dimensional Aggregation A Fundamental Introduction to Genetic Algorithm -Part Two TAI #200: Anthropic’s Mythos Capability Step Change and Gated Release From Notebook to Production: Running ML in the Real World (Part 4) Sqribble’s Template‑Driven Document Automation Anthropic Just Shipped the Layer That’s Already Going to Zero Long-Term vs Short-Term Memory for AI Agents: A Practical Guide Without the Hype The L1 Loss Gradient, Explained From Scratch Your Postcode Is Deciding Your Care. I Built a Pipeline to Prove It. I Directed AI Agents to Build a Tool That Stress-Tests Incentive Designs. Here’s What It Found. Your System Prompt Is the Product — Not the Feature The LLM Wiki Trend Has a Retention Problem Nobody Mentions Top 20 Data Preparation Interview Questions and Answers (Part 2 of 2) LAI #122: Word Embeddings Started in 1948, Not With Word2Vec Top 15 Computer Vision Datasets [2026] 40 Generative AI Interview Questions That Actually Get Asked in 2026 (With Answers)
Unleashing the Power of ONNX for Speedier SBERT Inference
Editorial Team · 2026-05-19 · via Towards AI

Author(s): Swaraj Patil

Originally published on Towards AI.

SBERT, also known as Sentence-Bert, is a widely used approach for obtaining sentence embeddings that aim to retain the contextual information within the sentences. However, generating these embeddings can be slow when dealing with large amounts of data. To address this, one option is to utilize batch-based encoding to accelerate the inference. However, this may not necessarily reduce the inference time. In this Medium blog post, we will explore the application of the ONNX (Open Neural Network Exchange) framework and how it aids in reducing the inference time of the model.

Unleashing the Power of ONNX for Speedier SBERT Inference

P.S. This article does not delve into the internal workings of ONNX. For more in-depth information, please consult the official ONNX documentation.

Let’s begin by installing the import libraries. We can use pip for the installation of ONNX

pip install onnx
pip install onnxruntime-gpu
pip install transformers
pip install torch

Once ONNX is installed we verify it using the below snippet

import onnx
print(onnx.__version__)

In order to obtain sentence embeddings, we will utilize the IMDB dataset sourced from Kaggle. Specifically, we will focus on the “Overview of Movie” column to generate embeddings using SBERT. The time needed to create embeddings will be determined for the 1000 sentences present in the dataset.

We will perform two experiments here on both CPU and GPU

  • Inference time for 1000 sentences using Vanilla SBERT (CPU).
  • Inference time for 1000 sentences using ONNX converted SBERT (CPU).
  • Inference time for 1000 sentences using Vanilla SBERT (GPU).
  • Inference time for 1000 sentences using ONNX converted SBERT (GPU).

The Sentence BERT model that we would consider here is all-MiniLM-L6-v2

We can invoke the Sentence BERT model from the Hugging Face Library and the Sentence Transformer Library. The output embeddings from both the library will be the same. For our experiments, we will use the Hugging Face library. Remember that when we use the Hugging Face library after obtaining the embeddings, additional post-processing could be needed such as Pooling or Normalization. The different steps can be obtained from the model page on Hugging Face. Perform those steps to get final sentence embeddings.

Let's first convert the model to ONNX format.

# # Load pretrained model and tokenizer
from transformers import AutoModel, AutoTokenizer

model_name = "sentence-transformers/all-MiniLM-L6-v2"

tokenizer = AutoTokenizer.from_pretrained(model_name,
do_lower_case=True )

model = AutoModel.from_pretrained(model_name )

#Mean Pooling - Take attention mask into account for correct averaging
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0] #First element of model_output contains all token embeddings
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
temp = torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1),
min=1e-9)
return F.normalize(temp, p=2, dim=1)

# Get the first example data to run the model and export it to ONNX

sample = ['Hey, how are you today?']
inputs = tokenizer(sample,
padding=True,
truncation=True,
return_tensors="pt"
)

## Convert Model to ONNX Format
import os
import torch
device = torch.device("cpu")

# Set model to inference mode, which is required before exporting
# the model because some operators behave differently in
# inference and training mode.
model.eval()
model.to(device)

output_dir = os.path.join(".", "onnx_models")

if not os.path.exists(output_dir):
os.makedirs(output_dir)

export_model_path = os.path.join(output_dir, 'all_MiniLM_L6-v2.onnx')

with torch.no_grad():
symbolic_names = {0: 'batch_size', 1: 'max_seq_len'}
torch.onnx.export(model, # model being run
args=tuple(inputs.values()), # model input (or a tuple for multiple inputs)
f=export_model_path, # where to save the model (can be a file or file-like object)
opset_version=11, # the ONNX version to export the model to
do_constant_folding=True, # whether to execute constant folding for optimization
input_names=['input_ids', # the model's input names
'attention_mask',
'token_type_ids'],
output_names=['start', 'end'], # the model's output names
dynamic_axes={'input_ids': symbolic_names, # variable length axes
'attention_mask' : symbolic_names,
'token_type_ids' : symbolic_names,
'start' : symbolic_names,
'end' : symbolic_names})
print("Model exported at ", export_model_path)

Now that we have converted the Sentence BERT Model. Let’s get the stats for the models.

Vanilla SBERT (CPU)

The inference time obtained for the Vanilla SBERT model on the CPU can be found using the snippet below.

import time
import pandas as pd
import numpy as np

from tqdm import tqdm

df = pd.read_csv('./imdb_top_1000.csv', usecols=['Overview'])

total_samples = len(df)

latency = []
outputs_cpu = []
with torch.no_grad():
for i in tqdm(range(total_samples)):

data = [df.loc[i, "Overview"]]

inputs = tokenizer(data,
padding=True,
truncation=True,
return_tensors="pt"
)

start = time.time()
outputs_cpu.append(mean_pooling(model(**inputs),
inputs['attention_mask']
).cpu().detach().numpy())

latency.append(time.time() - start)

print("\n")
print("PyTorch {} Inference time = {} ms".format(device.type,
np.round(np.average(latency)*1000, 4)))

100%|██████████| 1000/1000 [00:36<00:00, 27.62it/s]
PyTorch cpu Inference time = 34.2605 ms

ONNX Converted SBERT (CPU)

The inference time obtained for the ONNX SBERT model on the CPU can be found using the below snippet.

import onnxruntime
import numpy as np

sess_options = onnxruntime.SessionOptions()

session = onnxruntime.InferenceSession(export_model_path,
sess_options,
providers=['CPUExecutionProvider'])

latency = []
ort_outputs_cpu = []

for i in tqdm(range(total_samples)):

data = [df.loc[i, "Overview"]]

inputs = tokenizer(data,
padding=True,
truncation=True,
return_tensors="pt"
)

ort_inputs = {k:v.cpu().numpy() for k, v in inputs.items()}

start = time.time()
op = session.run(None, ort_inputs)
op = torch.from_numpy(op[0])
ort_outputs_cpu.append(mean_pooling([op],
inputs['attention_mask']
).cpu().detach().numpy())
latency.append(time.time() - start)

print("\n")
print("OnnxRuntime {} Inference time = {} ms".format(device.type,
np.round(np.average(latency)*1000, 4)))

100%|██████████| 1000/1000 [00:16<00:00, 60.80it/s]
OnnxRuntime cpu Inference time = 15.5696 ms

Outputs

outputs_cpu[0][:,:10] ## Vanilla SBERT CPU Output

array([[-0.06326339, 0.0414625 , -0.04707527, -0.03361899, -0.02562934,
0.03499832, 0.00804075, -0.05042004, 0.00215668, -0.03816812]]
,
dtype=float32)

ort_outputs_cpu[0][:,:10] ## Onnx SBERT CPU Output

array([[-0.06326343, 0.04146247, -0.04707528, -0.033619 , -0.02562926,
0.03499835, 0.0080408 , -0.05042008, 0.00215669, -0.03816817]]
,
dtype=float32)

Vanilla SBERT (GPU)

The inference time obtained for the Vanilla SBERT model on the GPU can be found using the snippet below.

device = torch.device("cuda")

# Set model to inference mode, which is required before exporting
# the model because some operators behave differently in
# inference and training mode.

model.eval()
model.to(device)

total_samples = len(df)

latency = []
outputs_gpu = []
with torch.no_grad():
for i in tqdm(range(total_samples)):

data = [df.loc[i, "Overview"]]

inputs = tokenizer(data,
padding=True,
truncation=True,
return_tensors="pt"
).to(device)

start = time.time()
outputs_gpu.append(mean_pooling(model(**inputs),
inputs['attention_mask']).cpu().detach().numpy())
latency.append(time.time() - start)

print("\n")
print("PyTorch {} Inference time = {} ms".format(device.type,
np.round(np.average(latency)*1000, 4)))

100%|██████████| 1000/1000 [00:07<00:00, 135.29it/s]
PyTorch cuda Inference time = 6.737 ms

ONNX Converted SBERT (GPU)

The inference time obtained for the ONNX SBERT model on the GPU can be found using the snippet below.

import onnxruntime
import numpy as np

sess_options = onnxruntime.SessionOptions()

session = onnxruntime.InferenceSession(export_model_path,
sess_options,
providers=['CUDAExecutionProvider'])

latency = []
ort_outputs_gpu = []
for i in tqdm(range(total_samples)):

data = [df.loc[i, "Overview"]]

inputs = tokenizer(data,
padding=True,
truncation=True,
return_tensors="pt"
).to(device)

ort_inputs = {k:v.cpu().numpy() for k, v in inputs.items()}

start = time.time()
op = session.run(None, ort_inputs)
op = torch.from_numpy(op[0])
ort_outputs_gpu.append(mean_pooling([op],
inputs['attention_mask'].cpu()).cpu().detach().numpy())
latency.append(time.time() - start)

print("\n")
print("OnnxRuntime {} Inference time = {} ms".format(device.type,
np.round(np.average(latency)*1000, 4)))

100%|██████████| 1000/1000 [00:02<00:00, 373.49it/s]
OnnxRuntime cuda Inference time = 1.9466 ms

Outputs

outputs_gpu[0][:,:10] ## Vanilla SBERT GPU 

array([[-0.06326333, 0.04146247, -0.0470753 , -0.03361904, -0.02562935,
0.03499833, 0.00804079, -0.05042002, 0.00215669, -0.03816818]]
,
dtype=float32)

ort_outputs_gpu[0][:,:10] ## ONNX SBERT GPU

array([[-0.06326336, 0.04146249, -0.04707528, -0.03361899, -0.02562931,
0.03499832, 0.0080408 , -0.05042004, 0.00215668, -0.03816817]]
,
dtype=float32)

Summary Table

Conclusion

Based on the results obtained we can see that the ONNX-converted model takes significantly less time to get the sentence embedding without any loss in the data. The experiments were conducted on Google Colab with T4 GPU. Similar or better results can be expected from other hardware as well.

In ONNX, we can also have a Quantised version of SBERT. The quantized version would have int8 dtype. One can explore that as well. The Jupyter notebook for the complete experiments is added in the GitHub repo below for further reference.

GitHub – SP2203/onnx-sbert

Contribute to SP2203/onnx-sbert development by creating an account on GitHub.

github.com

References

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

If this was useful, consider giving it a clap, it really helps. I write about ML, AI, and technology. Follow me here on Medium so you don’t miss the next one.

📌 More from me:

Keras Implementation of LE-NET

AlexNet: Pioneering the Path to Modern Deep Learning

Smoothening noisy GNSS dataONN

Published via Towards AI