首次调用 TextEmbedding() 会触发模型下载和初始化,需保证网络可访问模型源;GPU 支持要单独安装 fastembed-gpu 包并显式传入 providers=["CUDAExecutionProvider"];embed() 返回生成器,需 list() 转换后才能取长度或转 numpy;在 zsh 下安装 qdrant-client[fastembed] 需加引号。
fastembed
qdrantApache-2.0活跃维护轻量级 Python 向量化库,无需 API 调用即可在本地快速生成高质量文本嵌入,适合 RAG 和向量检索场景。
Fast, Accurate, Lightweight Python library to make State of the Art Embedding
pip install fastembed
# 或 GPU 版本
pip install fastembed-gpuREADME 明确说明不要求 GPU,可在 CPU 上运行,适合 AWS Lambda 等 serverless 环境;GPU 需安装 fastembed-gpu 包并指定 CUDAExecutionProvider,README 提到支持 CUDA 12.x,未列出具体显卡型号与显存要求。
轻量快速的 Python 嵌入库,用 ONNX Runtime 生成文本、图像和多模态向量,无需 GPU 也能跑
轻量级 Python 向量化库,无需 API 调用即可在本地快速生成高质量文本嵌入,适合 RAG 和向量检索场景。
核心能力
- 基于 ONNX Runtime,不依赖 PyTorch 的 GB 级依赖
- 支持稠密、稀疏(SPLADE++)、ColBERT 晚交互等多种文本嵌入
- 提供图像嵌入与 ColPali 多模态晚交互嵌入
- 内置 CrossEncoder 重排器,可直接对候选文档打分
- 支持 add_custom_model 接入自定义或量化 ONNX 模型
容易踩的坑
- v0.9.1最新正式版2026-10-24 · 2026-10-24 18:32 UTC
Changelog
Features 🏎️
- #805 - run the
minishlabpotion models with numpy instead of ONNX, 1.9x to 2.6x faster on documents with unchanged outputs by @joein - #806 - speed up embedding a single text, such as a query, with the potion models by @joein
- #808 - add an
mmapoption for the potion models to memory-map the embedding matrix: it loads instantly and letsparallelworkers share one copy by @joein
Fixes 🔧
- #794 - raise a
ValueErrorwhen a custom model withPoolingType.DISABLEDreturns per-token output instead of sentence embeddings by @joein - #795 - reject custom cross-encoder names that differ from a registered one only by case, which silently resolved to the earlier model by @wToTw123
- #830 - allow Pillow 13 by @svaningelgem
Other
- #819 - switch the project to uv by @tbung
fastembed-gpu0.9.1 is released alongside, with the same changes.
- #805 - run the
- v0.9.02026-10-07 · 2026-10-07 16:39 UTC
查看更新说明
Changelog
Features 🏎️
- #640 -
token_count()loads only the tokenizer, not the ONNX model, whenlazy_load=Trueby @Mirochill @joein - #643 - add
lightonai/LateOnand the multilinguallightonai/mLateOnby @tekumara @joein - #655 - add
stemmerandstopwordsparameters toQdrant/bm25for languages without a Snowball stemmer, such as Polish by @Mohith26 @joein - #702 - add
ibm-granite/granite-embedding-small-english-r2by @Aryan-SINGH-GIT @joein - #743 - add
BAAI/bge-reranker-v2-m3and its int8 versionBAAI/bge-reranker-v2-m3-int8by @joein - #747 - speed up MUVERA document encoding for large
k_simvalues by @Pothan0 @joein - #751 - add
Qdrant/stella-en-400M-v5-doc-onnxfor documents and the small query encodersQdrant/constella-zeroandQdrant/constella-nanothat search its embeddings by @joein @Dylancouzon - #756 - add
output_nametoTextEmbedding.add_custom_model()to choose which ONNX output a custom model uses by @tuanzirwar @joein
Fixes 🔧
- #640 - fix BM42 and miniCOIL failing, and ColBERT keeping punctuation vectors, with
lazy_load=Trueandparallelby @Mirochill @joein - #642, #726, #727, #728, #729, #730, #732, #780, #787 - make model downloads more reliable: re-download corrupted cached files, retry on more network errors, time out on an unresponsive Hugging Face endpoint, and download built-in models from Hugging Face only (see Upgrade Notes) by @Dmheath1 @joein
- #670, #734 - fix a hang when a
parallelrun is stopped early, for example withbreakby @FU-max-boop @joein - #721 - raise a
ValueErrorfor abatch_sizebelow 1 by @adityaanikam @joein - #723 - fix the licenses listed for
Qdrant/colpali-v1.3-fp16(gemma) and the Unicom models (mit) by @joein - #725 - accept nearest-neighbor interpolation in Jina CLIP image preprocessing by @HuaTNA @joein
- #731 - match Jina's center crop in
jinaai/jina-clip-v1preprocessing, which was off by 1 px for some image sizes by @joein - #733 - raise a
ValueErrorwhen MUVERA encodes an empty multivector by @Pothan0 @joein - #746 - fix center crop returning undersized images when it pads by an odd number of pixels by @HuaTNA @joein
- #754 - return
float32instead offloat64embeddings from mean-pooling text models, such assentence-transformers/all-MiniLM-L6-v2(regression in 0.6.1) by @joein - #757 - fix loading models with
.onnx_dataweights from ahuggingface_hub>=1.32cache withonnxruntime>=1.24by @joein - #760, #761, #784 - fix
Qdrant/colmodernvbertimage embeddings in batches that mix aspect ratios, for portrait images, and for very thin images, and speed up its text queries (see Upgrade Notes) by @hulkbig @JesusMan0529 @joein - #768 - return
int64indices fromSparseEmbedding.from_dict({})by @RAMZI0TO99 @joein - #769 - fix a token ID overflow in
Qdrant/bm25query embeddings by @RAMZI0TO99 @joein - #770 - respect
cuda=Falseinparallelworkers, which ran on the GPU whenonnxruntime-gpuwas installed (regression in 0.8.0) by @RAMZI0TO99 @joein - #771 - respect
do_resize=Falsein ConvNeXT image preprocessing by @RAMZI0TO99 @joein - #773 - keep very small SPLADE weights by computing them with
log1pby @RAMZI0TO99 @joein - #775, #776 - honor the truncation and padding side from the model's tokenizer config by @hulkbig @joein
Upgrade Notes
- Built-in models now download from Hugging Face only, without the Google Cloud Storage (GCS) fallback some of them had. The GCS buckets stay open, so older versions keep working, and custom models still support both
urlandhfsources. GCS copies cached by older versions still load offline or when Hugging Face is unreachable, with aFutureWarning: load the model once online, then delete itsfast-<model name>dir. - We removed a stray 128-token limit from the Hugging Face configs of
sentence-transformers/all-MiniLM-L6-v2andQdrant/bm42-all-minilm-l6-v2-attentions(now 256 tokens), and `thenlper/gt
- #640 -
- v0.8.12026-09-22 · 2026-09-22 20:52 UTC
查看更新说明
Changelog
Features 🏎️
- #592 - add
google/embeddinggemma-300mby @joein - #651 - add
nomic-ai/nomic-embed-vision-v1.5andnomic-ai/nomic-embed-vision-v1.5-Q, which share an embedding space withnomic-ai/nomic-embed-text-v1.5for text-to-image search by @Dylancouzon - #652 - add inference-free SPLADE
opensearch-project/opensearch-neural-sparse-encoding-doc-v3-gte, which runs the model on documents only and encodes queries without inference by @joein - #678, #680 - add
Qwen/Qwen3-Embedding-0.6BandQwen/Qwen3-Embedding-0.6B-Q(the quantized model requiresonnxruntime>=1.23), plusPoolingType.LAST_TOKENfor custom models by @joein - #683 - add
google/siglip2-base-patch16-224toTextEmbeddingandImageEmbeddingby @joein - #692 - add Model2Vec static models
minishlab/potion-base-8M,minishlab/potion-retrieval-32M, andminishlab/potion-multilingual-128Mby @stephantul @Dylancouzon
Fixes 🔧
- #593, #707 - use canonical Hugging Face repo IDs for
BAAI/bge-base-en-v1.5andBAAI/bge-small-en-v1.5to avoid a redirect that broke downloads behind some proxies (see Upgrade Notes) by @Harnas @rastagan-git @joein - #623 - run the fp32 version of
jinaai/jina-embeddings-v2-base-deinstead of fp16, which fails ononnxruntime>=1.23(the download grows from 0.32 GB to 0.64 GB) by @joein - #624 - check that model files exist before using a cached model, so several variants of one repo (for example fp32 and quantized) can share a cache dir by @joein
- #629 - add a timeout to downloads from Google Cloud Storage (GCS), so a stalled connection fails instead of hanging indefinitely by @joein
- #645 - fix a
KeyErrorwhen loading a custom text model with different casing than it was registered with by @CODING-DARSH @joein - #647 - fix a path traversal vulnerability in model archive extraction that could write files outside the cache dir by @he-yufeng @joein
- #682 - fix normalization of batched
(N, C, H, W)image arrays, which ran along the wrong axis by @serhiizghama @joein - #693 - make
config.jsonandspecial_tokens_map.jsonoptional when loading a tokenizer by @libaojiang @joein - #697 - fix the
Resizetransform swapping height and width for non-square sizes by @Ramnath0521 @joein - #714 - fix custom text embedding and cross-encoder models (
add_custom_model) failing whenparallelis set by @joein @S0rryHorizon - #716, #717 - always pad a batch to its longest sequence, fixing a
ValueErroron mixed-length batches for models whose tokenizer ships a fixed padding length, such asthenlper/gte-base(regression in 0.8.0) by @joein @mohmedmm - #718 - stage each GCS download in its own temporary dir, so a failed or concurrent download can't delete files from other downloads by @joein
Upgrade Notes
BAAI/bge-small-en-v1.5(the default model) andBAAI/bge-base-en-v1.5now resolve toQdrant/bge-small-en-v1.5-onnx-QandQdrant/bge-base-en-v1.5-onnx-Q. The cache dir name follows the repo ID's casing, so on case-sensitive filesystems (typically Linux) the existing cache isn't reused and both models download again once. Offline setups (HF_HUB_OFFLINE=1orlocal_files_only=True) need to refresh their cache before upgrading. You can delete the oldmodels--qdrant--bge-*-onnx-qdirs afterwards.jinaai/jina-embeddings-v2-base-denow loadsonnx/model.onnxinstead ofonnx/model_fp16.onnx, so offline setups need to download it first.
Thanks to everyone who contributed to this release @CODING-DARSH @Dylancouzon @Harnas @he-yufeng @libaojiang @mohmedmm @Ramnath0521 @rastagan-git @S0rryHorizon @serhiizghama @stephantul @joein
- #592 - add
- v0.8.02026-03-23 · 2026-03-23 17:14 UTC
查看更新说明
Changelog
Features 🏎️
- #537 - use cuda if available, instead of requiring explicit
cuda=True - #588 - add colmodernvbert by @kacperlukawski @joein
Fixes 🔧
- #534 - update colbert description by @joein
- #611 - fix onnxruntime and pillow versions for better 3.14 support and avoiding security issues caused by pillow
- #614 - respect HF_HUB_OFFLINE env by @amasolov
Deprecations
- #574 - drop python3.9 by @joein
Thanks to everyone who contributed to this release @joein @amasolov @kacperlukawski
- #537 - use cuda if available, instead of requiring explicit
- v0.7.42025-12-05 · 2025-12-05 12:18 UTC
查看更新说明
Changelog
Features 🏎️
- #577 - don't do any network calls if model is loaded from cache @joein
- #578 - expose
enable_cpu_mem_arenaonnx session option to handle onnxruntime memory allocation by @joein - #582 - unlock hf hub and pillow versions by @joein
- #583 - add a new
token_countmethod to text models by @joein @dancixx
Fixes 🕸️
- #585 - more granular numpy versioning
Thanks to everyone who contributed to this release @dancixx @joein and @tbung for all the reviews
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
⚡️ What is FastEmbed?
FastEmbed is a lightweight, fast, Python library built for embedding generation. We support popular text models. Please open a GitHub issue if you want us to add a new model.
The default text embedding (TextEmbedding) model is Flag Embedding, presented in the MTEB leaderboard. It supports "query" and "passage" prefixes for the input text. Here is an example for Retrieval Embedding Generation and how to use FastEmbed with Qdrant.
📈 Why FastEmbed?
-
Light: FastEmbed is a lightweight library with few external dependencies. We don't require a GPU and don't download GBs of PyTorch dependencies, and instead use the ONNX Runtime. This makes it a great candidate for serverless runtimes like AWS Lambda.
-
Fast: FastEmbed is designed for speed. We use the ONNX Runtime, which is faster than PyTorch. We also use data parallelism for encoding large datasets.
-
Accurate: FastEmbed is better than OpenAI Ada-002. We also support an ever-expanding set of models, including a few multilingual models.
🚀 Installation
To install the FastEmbed library, pip works best. You can install it with or without GPU support:
pip install fastembed
# or with GPU support
pip install fastembed-gpu
📖 Quickstart
from fastembed import TextEmbedding
# Example list of documents
documents: list[str] = [
"This is built to be faster and lighter than other embedding libraries e.g. Transformers, Sentence-Transformers, etc.",
"fastembed is supported by and maintained by Qdrant.",
]
# This will trigger the model download and initialization
embedding_model = TextEmbedding()
print("The model BAAI/bge-small-en-v1.5 is ready to use.")
embeddings_generator = embedding_model.embed(documents) # reminder this is a generator
embeddings_list = list(embedding_model.embed(documents))
# you can also convert the generator to a list, and that to a numpy array
len(embeddings_list[0]) # Vector of 384 dimensions
Fastembed supports a variety of models for different tasks and modalities. The list of all the available models can be found here
🎒 Dense text embeddings
from fastembed import TextEmbedding
model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
embeddings = list(model.embed(documents))
# [
# array([-0.1115, 0.0097, 0.0052, 0.0195, ...], dtype=float32),
# array([-0.1019, 0.0635, -0.0332, 0.0522, ...], dtype=float32)
# ]
Dense text embedding can also be extended with models which are not in the list of supported models.
from fastembed import TextEmbedding
from fastembed.common.model_description import PoolingType, ModelSource
TextEmbedding.add_custom_model(
model="intfloat/multilingual-e5-small",
pooling=PoolingType.MEAN,
normalization=True,
sources=ModelSource(hf="intfloat/multilingual-e5-small"), # can be used with an `url` to load files from a private storage
dim=384,
model_file="onnx/model.onnx", # can be used to load an already supported model with another optimization or quantization, e.g. onnx/model_O4.onnx
)
model = TextEmbedding(model_name="intfloat/multilingual-e5-small")
embeddings = list(model.embed(documents))
🔱 Sparse text embeddings
- SPLADE++
from fastembed import SparseTextEmbedding
model = SparseTextEmbedding(model_name="prithivida/Splade_PP_en_v1")
embeddings = list(model.embed(documents))
# [
# SparseEmbedding(indices=[ 17, 123, 919, ... ], values=[0.71, 0.22, 0.39, ...]),
# SparseEmbedding(indices=[ 38, 12, 91, ... ], values=[0.11, 0.22, 0.39, ...])
# ]
🦥 Late interaction models (aka ColBERT)
from fastembed import LateInteractionTextEmbedding
model = LateInteractionTextEmbedding(model_name="colbert-ir/colbertv2.0")
embeddings = list(model.embed(documents))
# [
# array([
# [-0.1115, 0.0097, 0.0052, 0.0195, ...],
# [-0.1019, 0.0635, -0.0332, 0.0522, ...],
# ]),
# array([
# [-0.9019, 0.0335, -0.0032, 0.0991, ...],
# [-0.2115, 0.8097, 0.1052, 0.0195, ...],
# ]),
# ]
🖼️ Image embeddings
from fastembed import ImageEmbedding
images = [
"./path/to/image1.jpg",
"./path/to/image2.jpg",
]
model = ImageEmbedding(model_name="Qdrant/clip-ViT-B-32-vision")
embeddings = list(model.embed(images))
# [
# array([-0.1115, 0.0097, 0.0052, 0.0195, ...], dtype=float32),
# array([-0.1019, 0.0635, -0.0332, 0.0522, ...], dtype=float32)
# ]
Late interaction multimodal models (ColPali)
from fastembed import LateInteractionMultimodalEmbedding
doc_images = [
"./path/to/qdrant_pdf_doc_1_screenshot.jpg",
"./path/to/colpali_pdf_doc_2_screenshot.jpg",
]
query = "What is Qdrant?"
model = LateInteractionMultimodalEmbedding(model_name="Qdrant/colpali-v1.3-fp16")
doc_images_embeddings = list(model.embed_image(doc_images))
# shape (2, 1030, 128)
# [array([[-0.03354, -0.0209, ..., -0.1558, -0.0768]], dtype=float16)]
query_embedding = model.embed_text(query)
# shape (1, 20, 128)
# [array([[-0.002182, 0.1476, ..., -0.02208, 0.1683]], dtype=float16)]
🔄 Rerankers
from fastembed.rerank.cross_encoder import TextCrossEncoder
query = "Who is maintaining Qdrant?"
documents: list[str] = [
"This is built to be faster and lighter than other embedding libraries e.g. Transformers, Sentence-Transformers, etc.",
"fastembed is supported by and maintained by Qdrant.",
]
encoder = TextCrossEncoder(model_name="Xenova/ms-marco-MiniLM-L-6-v2")
scores = list(encoder.rerank(query, documents))
# [-11.48061752319336, 5.472434997558594]
Text cross encoders can also be extended with models which are not in the list of supported models.
from fastembed.rerank.cross_encoder import TextCrossEncoder
from fastembed.common.model_description import ModelSource
TextCrossEncoder.add_custom_model(
model="Xenova/ms-marco-MiniLM-L-4-v2",
model_file="onnx/model.onnx",
sources=ModelSource(hf="Xenova/ms-marco-MiniLM-L-4-v2"),
)
model = TextCrossEncoder(model_name="Xenova/ms-marco-MiniLM-L-4-v2")
scores = list(model.rerank_pairs(
[("What is AI?", "Artificial intelligence is ..."), ("What is ML?", "Machine learning is ..."),]
))
⚡️ FastEmbed on a GPU
FastEmbed supports running on GPU devices.
It requires installation of the fastembed-gpu package.
pip install fastembed-gpu
Check our example for detailed instructions, CUDA 12.x support and troubleshooting of the common issues.
from fastembed import TextEmbedding
embedding_model = TextEmbedding(
model_name="BAAI/bge-small-en-v1.5",
providers=["CUDAExecutionProvider"]
)
print("The model BAAI/bge-small-en-v1.5 is ready to use on a GPU.")
Usage with Qdrant
Installation with Qdrant Client in Python:
pip install qdrant-client[fastembed]
or
pip install qdrant-client[fastembed-gpu]
You might have to use quotes pip install 'qdrant-client[fastembed]' on zsh.
from qdrant_client import QdrantClient, models
# Initialize the client
client = QdrantClient("localhost", port=6333) # For production
# client = QdrantClient(":memory:") # For experimentation
model_name = "sentence-transformers/all-MiniLM-L6-v2"
payload = [
{"document": "Qdrant has Langchain integrations", "source": "Langchain-docs", },
{"document": "Qdrant also has Llama Index integrations", "source": "LlamaIndex-docs"},
]
docs = [models.Document(text=data["document"], model=model_name) for data in payload]
ids = [42, 2]
client.create_collection(
"demo_collection",
vectors_config=models.VectorParams(
size=client.get_embedding_size(model_name), distance=models.Distance.COSINE)
)
client.upload_collection(
collection_name="demo_collection",
vectors=docs,
ids=ids,
payload=payload,
)
search_result = client.query_points(
collection_name="demo_collection",
query=models.Document(text="This is a query document", model=model_name)
).points
print(search_result)