Skip to main content

This project continues as fastretrieval. qwen3-embed on PyPI remains an active legacy distribution for existing users and continues to receive security fixes. Wet, Mnemo, and CRG have migrated their retrieval runtime to fastretrieval; new features land in fastretrieval only.

Qwen3 Embed

Lightweight Qwen3 text embedding and reranking via ONNX Runtime and GGUF

CI codecov PyPI License: Apache-2.0

Python ONNX Runtime Hugging Face semantic-release Renovate

Sister projects from n24q02m (click to expand)
Project Tagline Tag
agent-chat-plugin Peer AI agents chat in a shared folder — no human relay, no orchestrator, wor... Tooling
better-code-review-graph Knowledge graph for token-efficient code reviews -- semantic search and call-... MCP
better-drive 2-way Google Drive sync with .driveignore filter — rclone engine, Windows tray Tooling
better-email-mcp IMAP/SMTP email for AI agents -- read, send, organize folders, and manage att... MCP
better-godot-mcp Composite MCP server for Godot Engine -- 17 composite tools for AI-assisted g... MCP
better-notion-mcp Markdown-first Notion for AI agents -- pages, databases, blocks, and comments... MCP
better-semantic-release Drop-in python-semantic-release fork with built-in release-safety guards (orp... Tooling
better-telegram-mcp Telegram for AI agents -- messages, chats, media, and contacts across both bo... MCP
better-workspace-mcp Google Workspace MCP server (Docs/Drive/Calendar/Gmail/Sheets/Slides/Tasks/Ch... MCP
claude-plugins Claude Code plugin marketplace for the n24q02m MCP servers -- install web sea... Marketplace
imagine-mcp Image and video understanding + generation for AI agents -- across Gemini, Op... MCP
jules-task-archiver Chrome Extension for bulk operations on Jules tasks via batchexecute API -- a... Tooling
mcp-core Shared foundation for building MCP servers -- Streamable HTTP transport, OAut... MCP
mnemo-mcp Persistent AI memory with hybrid search and embedded sync. Open, free, unlimi... MCP
qwen3-embed Lightweight Qwen3 text embedding and reranking via ONNX Runtime and GGUF Library
skret Secrets without the server. CLI
tacet A self-distilling neuro-symbolic cascade that amortises LLM cost across knowl... Tooling
web-core Shared web infrastructure package for search, scraping, HTTP security, and st... Library
wet-mcp Open-source MCP server for AI agents: web search, content extraction, and lib... MCP

What it is

qwen3-embed is a lightweight Python library for text embedding and reranking with Qwen3 0.6B models. It runs on ONNX Runtime or GGUF (llama-cpp-python) with no PyTorch dependency, supports Matryoshka (MRL) truncation, instruction-aware queries, and optional GPU acceleration. It is a trimmed fork of fastembed that keeps only the Qwen3 models, and any ONNX-able model can be registered as a custom model.

Table of contents

Features

  • Last-token pooling: Uses the final token representation (with left-padding) instead of mean pooling.
  • MRL support: Matryoshka Representation Learning allows truncating embeddings to any dimension from 32 to 1024 while preserving quality.
  • Instruction-aware: Query embedding supports task instructions for better retrieval performance.
  • Causal LM reranking: Reranker uses yes/no logit scoring via causal language model, producing calibrated [0, 1] scores.
  • Multiple backends: ONNX Runtime (INT8, Q4F16) and GGUF (Q4_K_M via llama-cpp-python).
  • GPU optional, no PyTorch: Runs on ONNX Runtime or llama-cpp-python -- no heavy ML framework required. Auto-detects GPU (CUDA, DirectML) when available.
  • Multilingual: Both models support multi-language inputs.

Supported Models

ONNX (default)

Model Type Dims Max Tokens Size
n24q02m/Qwen3-Embedding-0.6B-ONNX Embedding 32-1024 (MRL) 32768 573 MB
n24q02m/Qwen3-Embedding-0.6B-ONNX-Q4F16 Embedding 32-1024 (MRL) 32768 517 MB
n24q02m/Qwen3-Reranker-0.6B-ONNX Reranker - 40960 573 MB
n24q02m/Qwen3-Reranker-0.6B-ONNX-Q4F16 Reranker - 40960 518 MB
n24q02m/Qwen3-Reranker-0.6B-ONNX-YesNo Reranker - 40960 598 MB

GGUF (optional, requires llama-cpp-python)

Model Type Dims Max Tokens Size
n24q02m/Qwen3-Embedding-0.6B-GGUF Embedding 32-1024 (MRL) 32768 378 MB
n24q02m/Qwen3-Reranker-0.6B-GGUF Reranker - 40960 378 MB

HuggingFace Repos

Format Embedding Reranker
ONNX n24q02m/Qwen3-Embedding-0.6B-ONNX n24q02m/Qwen3-Reranker-0.6B-ONNX
GGUF n24q02m/Qwen3-Embedding-0.6B-GGUF n24q02m/Qwen3-Reranker-0.6B-GGUF

Installation

pip install qwen3-embed

# For GGUF support
pip install qwen3-embed[gguf]

Usage

Text Embedding

from qwen3_embed import TextEmbedding

# INT8 (default)
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-ONNX")

# Q4F16 (smaller, slightly less accurate)
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-ONNX-Q4F16")

# GGUF (requires: pip install qwen3-embed[gguf])
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-GGUF")

documents = [
    "Qwen3 is a multilingual embedding model.",
    "ONNX Runtime enables fast CPU inference.",
]

embeddings = list(model.embed(documents))
# Each embedding: numpy array of shape (1024,), L2-normalized

# Matryoshka Representation Learning (MRL) -- truncate to smaller dims
embeddings_256 = list(model.embed(documents, dim=256))
# Each embedding: numpy array of shape (256,), L2-normalized

# Query with instruction (for retrieval tasks)
queries = list(
    model.query_embed(
        ["What is Qwen3?"],
        task="Given a question, retrieve relevant passages",
    )
)

Reranking

from qwen3_embed import TextCrossEncoder

reranker = TextCrossEncoder(model_name="n24q02m/Qwen3-Reranker-0.6B-ONNX")

# YesNo variant: ~10x less RAM (~598MB vs ~12GB at inference)
# reranker = TextCrossEncoder(model_name="n24q02m/Qwen3-Reranker-0.6B-ONNX-YesNo")

query = "What is Qwen3?"
documents = [
    "Qwen3 is a series of large language models by Alibaba.",
    "The weather today is sunny.",
    "Qwen3-Embedding supports multilingual text embedding.",
]

scores = list(reranker.rerank(query, documents))
# scores: list of float in [0, 1], higher = more relevant

# Or rerank pairs directly
pairs = [
    ("What is AI?", "Artificial intelligence is a branch of computer science."),
    ("What is ML?", "Machine learning is a subset of AI."),
]
pair_scores = list(reranker.rerank_pairs(pairs))

Reranker determinism

Reranker scores are batch-invariant: the score of a (query, document) pair does not depend on batch size or the other documents scored in the same call. ONNX reranker variants are scored one sequence at a time (no padding), which keeps RoPE positions correct regardless of batch composition. See issue #725.

Custom models (bring your own)

Qwen3 is the only built-in model, but any ONNX-able embedding model can be registered and then loaded by id. Use CustomModelSpec with one of the four output shapes: CLS/MEAN (bert-bi), LAST_TOKEN (causal), or DISABLED (raw).

from qwen3_embed import CustomModelSpec, TextEmbedding

# Multilingual (incl. Vietnamese) + code, CLS-pooled, 768-dim
CustomModelSpec(
    model_id="onnx-community/gte-multilingual-base",
    hf="onnx-community/gte-multilingual-base",
    model_file="onnx/model_quantized.onnx",
    dim=768,
    pooling="CLS",
    normalization=True,
).register()

model = TextEmbedding("onnx-community/gte-multilingual-base")
embeddings = list(model.embed(["xin chào", "def add(a, b): return a + b"]))

Other verified examples: bge-m3 (pooling="CLS", dim=1024), EmbeddingGemma-300m (pooling="MEAN", dim=768). MRL truncation (embed(..., dim=256)) works for custom models whose vectors are Matryoshka-trained. Custom models are scored per-row, so — like the built-in INT8 reranker — their scores are batch-invariant by construction.

A BYO reranker registers the same way with CustomRerankerSpec. Any standard ONNX cross-encoder (a single relevance logit per pair — bge-reranker, gte-reranker, ms-marco, jina-reranker) works; there is no dim/pooling to set:

from qwen3_embed import CustomRerankerSpec, TextCrossEncoder

CustomRerankerSpec(
    model_id="onnx-community/gte-multilingual-reranker-base",
    hf="onnx-community/gte-multilingual-reranker-base",
    model_file="onnx/model_quantized.onnx",
).register()

encoder = TextCrossEncoder("onnx-community/gte-multilingual-reranker-base")
scores = list(encoder.rerank("xin chào", ["tài liệu A", "tài liệu B"]))

PyTorch-only models can be converted first (in a throwaway env, since the export deps don't co-resolve with the lean runtime pins):

# pip install "optimum[exporters]" torch transformers onnx
from qwen3_embed.export import export_to_onnx

export_to_onnx("intfloat/multilingual-e5-base", "./e5-onnx")

Configuration

GPU Acceleration

Both ONNX and GGUF backends auto-detect GPU when available (Device.AUTO is the default).

ONNX

Requires onnxruntime-gpu (CUDA) or onnxruntime-directml (Windows) instead of onnxruntime:

pip install onnxruntime-gpu  # NVIDIA CUDA
# or
pip install onnxruntime-directml  # Windows AMD/Intel/NVIDIA
from qwen3_embed import TextEmbedding, Device

# Auto-detect GPU (default)
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-ONNX")

# Force CPU
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-ONNX", cuda=Device.CPU)

# Force CUDA
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-ONNX", cuda=Device.CUDA)

GGUF

GPU is handled by llama-cpp-python. The default pip install qwen3-embed[gguf] is CPU-only. For CUDA GPU support, build with:

CMAKE_ARGS="-DGGML_CUDA=on" pip install qwen3-embed[gguf]
from qwen3_embed import TextEmbedding, Device

# Auto-detect GPU (default, offloads all layers)
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-GGUF")

# Force CPU only
model = TextEmbedding(model_name="n24q02m/Qwen3-Embedding-0.6B-GGUF", cuda=Device.CPU)

Development

uv sync --group dev                              # Install dev dependencies
uv run ruff check .                              # Lint
uv run ruff format --check .                     # Format check
uv run ty check                                  # Type check
uv run pytest                                    # All tests (integration tests download ~1.2 GB)
uv run pytest -m "not integration" --tb=short    # Unit tests only (CI default)

# Shortcuts (optional, via mise): mise run setup / lint / test / fix
  • wet-mcp -- MCP web search server with vector-based docs search, uses fastretrieval for local embedding
  • mnemo-mcp -- MCP memory server with semantic search powered by fastretrieval
  • better-code-review-graph -- Knowledge graph for code reviews, uses fastretrieval for local ONNX embedding
  • modalcom-ai-workers -- GPU-serverless workers that convert Qwen3 models to ONNX/GGUF format

Contributing

See CONTRIBUTING.md.

License

Apache-2.0 -- See LICENSE. Original fastembed by Qdrant.

Metadata

Release files for qwen3-embed 1.14.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qwen3-embed 1.14.0
File Size Uploaded
qwen3_embed-1.14.0.tar.gz 243.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qwen3-embed 1.14.0
File Interpreter ABI Platform
qwen3_embed-1.14.0-py3-none-any.whl Python 3 none any Details

Total release size: 313.8 kB

Release files / qwen3_embed-1.14.0.tar.gz

Download URL qwen3_embed-1.14.0.tar.gz
Size 243.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1cf612d087d3ca54e75fd76157f82f689e41df164ed7f8fb5d8c1a781a538073
BLAKE2b-256 checksum
How to use checksums
f6cbae81eaf04f3daf59602ca72bbc3375c2beb2708d5cd5266c9981890b6cb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / qwen3_embed-1.14.0-py3-none-any.whl

Download URL qwen3_embed-1.14.0-py3-none-any.whl
Size 70.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45ed7928b9bf9845eac20f7ccf2a2a4e97eb524bf6517bcc55f18f244f047f19
BLAKE2b-256 checksum
How to use checksums
43d7d1df7d2f73606893f9a3b1aff63157c0ebf61cdc785fbc0901150991694b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.14.0 This release

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.3

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page