GPU 运行前需先安装 NVIDIA Container Toolkit,且驱动要兼容 CUDA 12.2+;容器内服务监听 80 端口,需映射到宿主机端口(示例为 8080);挂载 /data 卷可避免每次启动重复下载模型权重。

text-embeddings-inference
huggingfaceApache-2.0活跃维护面向文本嵌入模型的高性能推理服务,用 Rust 编写,可快速把文本转成向量,适合搭建检索和 RAG 的向量化后端。
A blazing fast inference solution for text embeddings models
model=Qwen/Qwen3-Embedding-0.6B
docker run --gpus all -p 8080:80 -v $PWD/data:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id $modelREADME 示例使用 NVIDIA A10,GPU 需装 NVIDIA Container Toolkit,驱动需兼容 CUDA 12.2 及以上;另有 AMD Instinct(ROCm)与 Apple Silicon(Metal/Homebrew)支持。README 未给出具体显存数值。
Hugging Face 出品的文本嵌入模型推理服务,把开源 embedding 模型快速部署成生产级 API
面向文本嵌入模型的高性能推理服务,用 Rust 编写,可快速把文本转成向量,适合搭建检索和 RAG 的向量化后端。
核心能力
- 基于 token 的动态批处理提升吞吐
- 用 Flash Attention、Candle 和 cuBLASLt 优化推理
- 支持 Safetensors 与 ONNX 权重加载
- 无需模型图编译步骤,镜像小启动快
- 内置 OpenTelemetry 链路追踪与 Prometheus 指标
容易踩的坑
- v1.9.4最新正式版2026-09-15 · 2026-09-15 09:28 UTC
What's Changed
- Add Dockerfile for ARM64 architecture support and update README instructions by @z4y4ts in https://github.com/huggingface/text-embeddings-inference/pull/827
- feat: multi-arch CUDA Dockerfile and sm_121 (DGX Spark GB10) by @nazq in https://github.com/huggingface/text-embeddings-inference/pull/840
- feat: update
metricspackage to support modern rust by @daeho-ro in https://github.com/huggingface/text-embeddings-inference/pull/850 - Support
harrier-oss-v1model by @kozistr in https://github.com/huggingface/text-embeddings-inference/pull/854 - Fix to only build
Dockerfile-cudaw/ Blackwell 12.1 on linux/arm64 by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/852 - Add minimal AMD ROCm GPU support by @Abdennacer-Badaoui in https://github.com/huggingface/text-embeddings-inference/pull/853
- 🔒 Pin GitHub Actions to commit SHAs by @paulinebm in https://github.com/huggingface/text-embeddings-inference/pull/855
- Add dedicated linux/arm64 runner by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/858
- [AMD] Add Instinct GPU setup guide by @Abdennacer-Badaoui in https://github.com/huggingface/text-embeddings-inference/pull/856
- chore: bump doc-builder SHA for PR upload workflow by @rtrompier in https://github.com/huggingface/text-embeddings-inference/pull/862
- fix(entrypoint): add /usr/local/nvidia to PATH and ldconfig on GKE by @oOraph in https://github.com/huggingface/text-embeddings-inference/pull/877
- Add default user-agent header by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/892
- Fix
max_position_embeddingshandling inNomicBertConfigandFlashNomicBertConfigby @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/876 - fix(docker): detect CUDA version from
CUDA UMD Versionheader on driver 6xx (#870) by @Anai-Guo in https://github.com/huggingface/text-embeddings-inference/pull/871 - Align
cuda-{all-entrypoint,entrypoint}.shby @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/893 - DebertaV2 fix for running with large batches by @vrdn-23 in https://github.com/huggingface/text-embeddings-inference/pull/846
- Fix link to AMD Instinct GPU guide in README by @manickavela-uni in https://github.com/huggingface/text-embeddings-inference/pull/898
- Fix Cloud Run CLI argument documentation by @cupkk in https://github.com/huggingface/text-embeddings-inference/pull/901
- Fix single predict request metrics by @original4422 in https://github.com/huggingface/text-embeddings-inference/pull/917
- Quality: Unbounded buffer allocation in PaddedBatch.from_pb by @kumburovicbranko682-boop in https://github.com/huggingface/text-embeddings-inference/pull/890
- feat: ROCm flash-attn varlen, triton layer norm, and AMD Dockerfile by @Abdennacer-Badaoui in https://github.com/huggingface/text-embeddings-inference/pull/860
- Update
versionto 1.9.4 & runcargo updateby @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/928
New Contributors
- @z4y4ts made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/827
- @nazq made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/840
- @daeho-ro made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/850
- @Abdennacer-Badaoui made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/853
- @paulinebm made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/855
- @rtrompier made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/862
- @oOraph made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/877
- @Anai-Guo made their first contribution in https://github.com/huggingface/text-embeddings-inference
- v1.9.32026-03-23 · 2026-03-23 11:57 UTC
查看更新说明
What's Changed
- Use
rust-toolchain.tomlbeforerustuponDockerfile-{cuda,cuda-all}by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/842 - fix(backend): replace bare except with Exception in device check by @llukito in https://github.com/huggingface/text-embeddings-inference/pull/821
- Set
version1.9.3 by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/849
New Contributors
- @llukito made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/821
Full Changelog: https://github.com/huggingface/text-embeddings-inference/compare/v1.9.2...v1.9.3
- Use
- v1.9.22026-02-25 · 2026-02-25 11:17 UTC
查看更新说明
What's Changed
- Fix auto-truncate false setting by @vrdn-23 in https://github.com/huggingface/text-embeddings-inference/pull/836
- Set
pad_token_idas nullable & add support forrope_parametersby @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/832 - docs: add Homebrew installation to README by @Peredery in https://github.com/huggingface/text-embeddings-inference/pull/834
- feat: support pplx-embed-v1 by @mkrimmel-pplx in https://github.com/huggingface/text-embeddings-inference/pull/824
New Contributors
- @Peredery made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/834
- @mkrimmel-pplx made their first contribution in https://github.com/huggingface/text-embeddings-inference/pull/824
Full Changelog: https://github.com/huggingface/text-embeddings-inference/compare/v1.9.1...v1.9.2
- v1.9.12026-02-17 · 2026-02-17 20:59 UTC
查看更新说明
What's Changed
🚨 Fix
- Fix support for containers w/ CUDA 13.0+ by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/831
When releasing ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 with CUDA 12.9 and
cuda-compat-12-9there was an issue when running that same container on instances with CUDA 13.0+, as thecuda-compat-12-9set inLD_LIBRARY_PATHwas leading to aCUDA_ERROR_SYSTEM_DRIVER_MISMATCH = 803, which is now solved with a custom entrypoint that dynamically includes thecuda-compaton theLD_LIBRARY_PATHdepending on the instance CUDA version.Full Changelog: https://github.com/huggingface/text-embeddings-inference/compare/v1.9.0...v1.9.1
- v1.9.02026-02-17 · 2026-02-17 13:42 UTC
查看更新说明
What's changed?
🚨 Breaking changes
- Default
HiddenAct::Geluto GeLU + tanh in favour of GeLU erf by @vrdn-23 in https://github.com/huggingface/text-embeddings-inference/pull/753
Default GeLU implementation is now GeLU + tanh approximation instead of exact GeLU (aka. GeLU erf) to make sure that the CPU and CUDA embeddings are the same (as cuBLASlt only supports GeLU + tanh), which represents a slight misalignment from how Transformers handles it, as when
hidden_act="gelu"is set inconfig.json, GeLU erf should be used. The numerical differences between GeLU + tanh and GeLU erf should have negligible impact on inference quality.- Set
--auto-truncatetotrueby default by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/829
--auto-truncatenow defaults to true, meaning that the sequences will be truncated to the lower value between the--max-batch-tokensor the maximum model length, to prevent the--max-batch-tokensfrom being lower than the actual maximum supported length.🎉 Additions
- Add
--served-model-namefor OpenAI requests via HTTP by @vrdn-23 in https://github.com/huggingface/text-embeddings-inference/pull/685 - Extend
download_onnxto download sharded ONNX by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/817 - Add support for llama 2 by @michaelfeil in https://github.com/huggingface/text-embeddings-inference/pull/802
- Add support for blackwell architecture (sm100, sm120) by @danielealbano in https://github.com/huggingface/text-embeddings-inference/pull/735
- Mf/add-support-for-llama-3-and-nemotron by @michaelfeil in https://github.com/huggingface/text-embeddings-inference/pull/805
- Add support for DebertaV2 by @vrdn-23 in https://github.com/huggingface/text-embeddings-inference/pull/746
- Add bidirectional attention and projection layer support for Qwen3-based models by @williambarberjr in https://github.com/huggingface/text-embeddings-inference/pull/808
🐛 Fixes
- Fix reading non-standard config for
past_key_valuesin ONNX by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/751 - Fix
TruncationDirectionto deserialize from lowercase and capitalized by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/755 - Fix
sagemaker-entrypoint*& remove SageMaker and Vertex fromDockerfile*by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/699 - Bug: Critical accuracy bugs for model_type=qwen2: no causal attention and wrong tokenizer by @michaelfeil in https://github.com/huggingface/text-embeddings-inference/pull/762
- Fix
config.jsonreading w/ aliases for ORT by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/786 - Fix HTTP error code for validation by @vrdn-23 in https://github.com/huggingface/text-embeddings-inference/pull/818
- Fix to acquire the permit in a blocking way by @kozistr in https://github.com/huggingface/text-embeddings-inference/pull/726
- Read Hugging Face Hub token from cache if not provided by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/814
- Align the
normalizeparam between the gRPC and HTTP /embed interfaces by @kozistr in https://github.com/huggingface/text-embeddings-inference/pull/810
⚡ Improvements
- Serialization in tokio thread instead of blocking thread, 50% reduction in latency for small models by @michaelfeil in https://github.com/huggingface/text-embeddings-inference/pull/767
- Remove default
--model-idargument by @alvarobartt in https://github.com/huggingface/text-embeddings-inference/pull/679 - feat: better Tokenization # workers heuristic by @michaelfeil in https://github.com/huggingface/text-embeddings-inference/pu
- Default
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Text Embeddings Inference
A blazing fast inference solution for text embeddings models.
Benchmark for BAAI/bge-base-en-v1.5 on an NVIDIA A10 with a sequence length of 512 tokens:
Table of contents
Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5. TEI implements many features such as:
- No model graph compilation step
- Metal support for local execution on Macs
- Small docker images and fast boot times. Get ready for true serverless!
- Token based dynamic batching
- Optimized transformers code for inference using Flash Attention, Candle and cuBLASLt
- Safetensors weight loading
- ONNX weight loading
- Production ready (distributed tracing with Open Telemetry, Prometheus metrics)
Get Started
Supported Models
Text Embeddings
Text Embeddings Inference currently supports Nomic, BERT, CamemBERT, XLM-RoBERTa models with absolute positions, JinaBERT model with Alibi positions and Mistral, Alibaba GTE, Qwen2 models with Rope positions, MPNet, ModernBERT, Qwen3, and Gemma3.
Below are some examples of the currently supported models:
To explore the list of best performing text embeddings models, visit the Massive Text Embedding Benchmark (MTEB) Leaderboard.
Sequence Classification and Re-Ranking
Text Embeddings Inference currently supports CamemBERT, and XLM-RoBERTa Sequence Classification models with absolute positions.
Below are some examples of the currently supported models:
| Task | Model Type | Model ID |
|---|---|---|
| Re-Ranking | XLM-RoBERTa | BAAI/bge-reranker-large |
| Re-Ranking | XLM-RoBERTa | BAAI/bge-reranker-base |
| Re-Ranking | GTE | Alibaba-NLP/gte-multilingual-reranker-base |
| Re-Ranking | ModernBert | Alibaba-NLP/gte-reranker-modernbert-base |
| Sentiment Analysis | RoBERTa | SamLowe/roberta-base-go_emotions |
Docker
model=Qwen/Qwen3-Embedding-0.6B
volume=$PWD/data # share a volume with the Docker container to avoid downloading weights every run
docker run --gpus all -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id $model
And then you can make requests like
curl 127.0.0.1:8080/embed \
-X POST \
-d '{"inputs":"What is Deep Learning?"}' \
-H 'Content-Type: application/json'
Note: To use GPUs, you need to install the NVIDIA Container Toolkit. NVIDIA drivers on your machine need to be compatible with CUDA version 12.2 or higher.
To see all options to serve your models:
$ text-embeddings-router --help
Text Embedding Webserver
Usage: text-embeddings-router [OPTIONS] --model-id <MODEL_ID>
Options:
--model-id <MODEL_ID>
The Hugging Face model ID, can be any model listed on <https://huggingface.co/models> with the `text-embeddings-inference` tag (meaning it's compatible with Text Embeddings Inference).
Alternatively, the specified ID can also be a path to a local directory containing the necessary model files saved by the `save_pretrained(...)` methods of either Transformers or Sentence Transformers.
[env: MODEL_ID=]
--revision <REVISION>
The actual revision of the model if you're referring to a model on the hub. You can use a specific commit id or a branch like `refs/pr/2`
[env: REVISION=]
--tokenization-workers <TOKENIZATION_WORKERS>
Optionally control the number of tokenizer workers used for payload tokenization, validation and truncation. Default to the number of CPU cores on the machine
[env: TOKENIZATION_WORKERS=]
--dtype <DTYPE>
The dtype to be forced upon the model
[env: DTYPE=]
[possible values: float16, float32]
--served-model-name <SERVED_MODEL_NAME>
The name of the model that is being served. If not specified, defaults to `--model-id`. It is only used for the OpenAI-compatible endpoints via HTTP
[env: SERVED_MODEL_NAME=]
--pooling <POOLING>
Optionally control the pooling method for embedding models.
If `pooling` is not set, the pooling configuration will be parsed from the model `1_Pooling/config.json` configuration.
If `pooling` is set, it will override the model pooling configuration
[env: POOLING=]
Possible values:
- cls: Select the CLS token as embedding
- mean: Apply Mean pooling to the model embeddings
- splade: Apply SPLADE (Sparse Lexical and Expansion) to the model embeddings. This option is only available if the loaded model is a `ForMaskedLM` Transformer model
- last-token: Select the last token as embedding
--max-concurrent-requests <MAX_CONCURRENT_REQUESTS>
The maximum amount of concurrent requests for this particular deployment. Having a low limit will refuse clients requests instead of having them wait for too long and is usually good to handle backpressure correctly
[env: MAX_CONCURRENT_REQUESTS=]
[default: 512]
--max-batch-tokens <MAX_BATCH_TOKENS>
**IMPORTANT** This is one critical control to allow maximum usage of the available hardware.
This represents the total amount of potential tokens within a batch.
For `max_batch_tokens=1000`, you could fit `10` queries of `total_tokens=100` or a single query of `1000` tokens.
Overall this number should be the largest possible until the model is compute bound. Since the actual memory overhead depends on the model implementation, text-embeddings-inference cannot infer this number automatically.
[env: MAX_BATCH_TOKENS=]
[default: 16384]
--max-batch-requests <MAX_BATCH_REQUESTS>
Optionally control the maximum number of individual requests in a batch
[env: MAX_BATCH_REQUESTS=]
--max-client-batch-size <MAX_CLIENT_BATCH_SIZE>
Control the maximum number of inputs that a client can send in a single request
[env: MAX_CLIENT_BATCH_SIZE=]
[default: 32]
--auto-truncate
Control automatic truncation of inputs that exceed the model's maximum supported size. Defaults to `true` (truncation enabled). Set to `false` to disable truncation; when disabled and the model's maximum input length exceeds `--max-batch-tokens`, the server will refuse to start with an error instead of silently truncating sequences.
Unused for gRPC servers
[env: AUTO_TRUNCATE=]
--default-prompt-name <DEFAULT_PROMPT_NAME>
The name of the prompt that should be used by default for encoding. If not set, no prompt will be applied.
Must be a key in the `sentence-transformers` configuration `prompts` dictionary.
For example if ``default_prompt_name`` is "query" and the ``prompts`` is {"query": "query: ", ...}, then the sentence "What is the capital of France?" will be encoded as "query: What is the capital of France?" because the prompt text will be prepended before any text to encode.
The argument '--default-prompt-name <DEFAULT_PROMPT_NAME>' cannot be used with '--default-prompt <DEFAULT_PROMPT>`
[env: DEFAULT_PROMPT_NAME=]
--default-prompt <DEFAULT_PROMPT>
The prompt that should be used by default for encoding. If not set, no prompt will be applied.
For example if ``default_prompt`` is "query: " then the sentence "What is the capital of France?" will be encoded as "query: What is the capital of France?" because the prompt text will be prepended before any text to encode.
The argument '--default-prompt <DEFAULT_PROMPT>' cannot be used with '--default-prompt-name <DEFAULT_PROMPT_NAME>`
[env: DEFAULT_PROMPT=]
--dense-path <DENSE_PATH>
Optionally, define the path to the Dense module required for some embedding models.
Some embedding models require an extra `Dense` module which contains a single Linear layer and an activation function. By default, those `Dense` modules are stored under the `2_Dense` directory, but there might be cases where different `Dense` modules are provided, to convert the pooled embeddings into different dimensions, available as `2_Dense_<dims>` e.g. https://huggingface.co/NovaSearch/stella_en_400M_v5.
Note that this argument is optional, only required to be set if there is no `modules.json` file or when you want to override a single Dense module path, only when running with the `candle` backend.
[env: DENSE_PATH=]
--hf-token <HF_TOKEN>
Your Hugging Face Hub token. If neither `--hf-token` nor `HF_TOKEN` are set, the token will be read from the `$HF_HOME/token` path, if it exists. This ensures access to private or gated models, and allows for a more permissive rate limiting
[env: HF_TOKEN=]
--hostname <HOSTNAME>
The IP address to listen on
[env: HOSTNAME=]
[default: 0.0.0.0]
-p, --port <PORT>
The port to listen on
[env: PORT=]
[default: 3000]
--root-path <ROOT_PATH>
Root path to mount all HTTP routes under.
For example, `--root-path jinaai/jina-embeddings-v2-base-en` serves the OpenAI-compatible embeddings route at `/jinaai/jina-embeddings-v2-base-en/v1/embeddings`.
Unused for gRPC servers.
[env: ROOT_PATH=]
--uds-path <UDS_PATH>
The name of the unix socket some text-embeddings-inference backends will use as they communicate internally with gRPC
[env: UDS_PATH=]
[default: /tmp/text-embeddings-inference-server]
--huggingface-hub-cache <HUGGINGFACE_HUB_CACHE>
The location of the huggingface hub cache. Used to override the location if you want to provide a mounted disk for instance
[env: HUGGINGFACE_HUB_CACHE=]
--payload-limit <PAYLOAD_LIMIT>
Payload size limit in bytes
Default is 2MB
[env: PAYLOAD_LIMIT=]
[default: 2000000]
--api-key <API_KEY>
Set an api key for request authorization.
By default the server responds to every request. With an api key set, the requests must have the Authorization header set with the api key as Bearer token.
[env: API_KEY=]
--json-output
Outputs the logs in JSON format (useful for telemetry). With an OTLP endpoint set, each log line also includes the trace_id and span_id of its span
[env: JSON_OUTPUT=]
--disable-spans
Whether or not to include the log trace through spans
[env: DISABLE_SPANS=]
--otlp-endpoint <OTLP_ENDPOINT>
The endpoint for OpenTelemetry traces. Use `http://localhost:4317` for gRPC or `http://localhost:4318` for HTTP. With `http-proto`, `/v1/traces` is appended to the endpoint path unless already present
[env: OTLP_ENDPOINT=]
--otlp-service-name <OTLP_SERVICE_NAME>
The service name for opentelemetry. e.g. `text-embeddings-inference.server`
[env: OTLP_SERVICE_NAME=]
[default: text-embeddings-inference.server]
--otlp-protocol <OTLP_PROTOCOL>
The protocol used to export OTLP traces: gRPC or HTTP with protobuf encoding
[env: OTLP_PROTOCOL=]
[default: grpc]
[possible values: grpc, http-proto]
--prometheus-port <PROMETHEUS_PORT>
The HTTP port for Prometheus metrics.
HTTP servers share the API port by default. Set a different port to serve metrics separately and remove `/metrics` from the API port. gRPC servers default to 9000.
[env: PROMETHEUS_PORT=]
--cors-allow-origin <CORS_ALLOW_ORIGIN>
Unused for gRPC servers
[env: CORS_ALLOW_ORIGIN=]
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
Docker Images
Text Embeddings Inference ships with multiple Docker images that you can use to target a specific backend:
| Architecture | Platform | Image |
|---|---|---|
| CPU | x86_64 | ghcr.io/huggingface/text-embeddings-inference:cpu-1.9 |
| CPU | aarch64 | ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9 |
| Volta | x86_64 | NOT SUPPORTED |
| Turing (T4, RTX 2000 series, ...) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:turing-1.9 (experimental) |
| Ampere 8.0 (A100, A30) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:1.9 |
| Ampere 8.6 (A10, A40, ...) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:86-1.9 |
| Ada Lovelace (RTX 4000 series, ...) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:89-1.9 |
| Hopper (H100) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:hopper-1.9 |
| Blackwell 10.0 (B200, GB200, ...) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:100-1.9 (experimental) |
| Blackwell 12.0 (GeForce RTX 50X0, ...) | x86_64 | ghcr.io/huggingface/text-embeddings-inference:120-1.9 (experimental) |
| Blackwell 12.1 (DGX Spark GB10, ...) | multi | ghcr.io/huggingface/text-embeddings-inference:121-1.9 (experimental) |
Warning: Flash Attention is turned off by default for the Turing image as it suffers from precision issues.
You can turn Flash Attention v1 ON by using the USE_FLASH_ATTENTION=True environment variable.
API documentation
You can consult the OpenAPI documentation of the text-embeddings-inference REST API using the /docs route.
The Swagger UI is also available
at: https://huggingface.github.io/text-embeddings-inference.
Using a private or gated model
You have the option to utilize the HF_TOKEN environment variable for configuring the token employed by
text-embeddings-inference. This allows you to gain access to protected resources.
For example:
- Go to https://huggingface.co/settings/tokens
- Copy your CLI READ token
- Export
HF_TOKEN=<your CLI READ token>
or with Docker:
model=<your private model>
volume=$PWD/data # share a volume with the Docker container to avoid downloading weights every run
token=<your CLI READ token>
docker run --gpus all -e HF_TOKEN=$token -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id $model
Air gapped deployment
To deploy Text Embeddings Inference in an air-gapped environment, first download the weights and then mount them inside the container using a volume.
For example:
# (Optional) create a `models` directory
mkdir models
cd models
# Make sure you have git-lfs installed (https://git-lfs.com)
git lfs install
git clone https://huggingface.co/Qwen/Qwen3-Embedding-0.6B
# Set the models directory as the volume path
volume=$PWD
# Mount the models directory inside the container with a volume and set the model ID
docker run --gpus all -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id /data/Qwen3-Embedding-0.6B
Using Re-rankers models
text-embeddings-inference v0.4.0 added support for CamemBERT, RoBERTa, XLM-RoBERTa, and GTE Sequence Classification models.
Re-rankers models are Sequence Classification cross-encoders models with a single class that scores the similarity
between a query and a text.
See this blogpost by the LlamaIndex team to understand how you can use re-rankers models in your RAG pipeline to improve downstream performance.
model=BAAI/bge-reranker-large
volume=$PWD/data # share a volume with the Docker container to avoid downloading weights every run
docker run --gpus all -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id $model
And then you can rank the similarity between a query and a list of texts with:
curl 127.0.0.1:8080/rerank \
-X POST \
-d '{"query": "What is Deep Learning?", "texts": ["Deep Learning is not...", "Deep learning is..."]}' \
-H 'Content-Type: application/json'
Using Sequence Classification models
You can also use classic Sequence Classification models like SamLowe/roberta-base-go_emotions:
model=SamLowe/roberta-base-go_emotions
volume=$PWD/data # share a volume with the Docker container to avoid downloading weights every run
docker run --gpus all -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id $model
Once you have deployed the model you can use the predict endpoint to get the emotions most associated with an input:
curl 127.0.0.1:8080/predict \
-X POST \
-d '{"inputs":"I like you."}' \
-H 'Content-Type: application/json'
Using SPLADE pooling
You can choose to activate SPLADE pooling for Bert and Distilbert MaskedLM architectures:
model=naver/efficient-splade-VI-BT-large-query
volume=$PWD/data # share a volume with the Docker container to avoid downloading weights every run
docker run --gpus all -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9 --model-id $model --pooling splade
Once you have deployed the model you can use the /embed_sparse endpoint to get the sparse embedding:
curl 127.0.0.1:8080/embed_sparse \
-X POST \
-d '{"inputs":"I like you."}' \
-H 'Content-Type: application/json'
Distributed Tracing
text-embeddings-inference is instrumented with distributed tracing using OpenTelemetry. You can use this feature
by setting the address to an OTLP collector with the --otlp-endpoint argument (or OTLP_ENDPOINT).
The default protocol is gRPC. To export OTLP over HTTP with protobuf encoding, use
--otlp-protocol http-proto (or OTLP_PROTOCOL=http-proto):
text-embeddings-router \
--model-id BAAI/bge-small-en-v1.5 \
--otlp-endpoint http://localhost:4318 \
--otlp-protocol http-proto
For HTTP, --otlp-endpoint accepts a base URL: /v1/traces is appended while preserving any path prefix.
For example, https://collector.example.com/otel exports to
https://collector.example.com/otel/v1/traces. A full endpoint already ending in /v1/traces
is also accepted. The router's HTTPS exporter uses the system's trusted root certificates.
For HTTP exports, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT takes priority (a full URL used unchanged),
followed by OTEL_EXPORTER_OTLP_ENDPOINT (a base URL with /v1/traces appended), then
--otlp-endpoint / OTLP_ENDPOINT. This order applies to both the router and Python backend.
--otlp-endpoint or OTLP_ENDPOINT is still required to enable tracing.
Both protocols support authentication and custom headers through OTEL_EXPORTER_OTLP_HEADERS
(comma-separated key=value pairs). Use percent-encoded values, for example
OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer%20token".
OTEL_EXPORTER_OTLP_TRACES_HEADERS, when set, replaces the general header list for trace exports.
These settings also apply to tracing in the Python backend.
gRPC
text-embeddings-inference offers a gRPC API as an alternative to the default HTTP API for high performance
deployments. The API protobuf definition can be
found here.
You can use the gRPC API by adding the -grpc tag to any TEI Docker image. For example:
model=Qwen/Qwen3-Embedding-0.6B
volume=$PWD/data # share a volume with the Docker container to avoid downloading weights every run
docker run --gpus all -p 8080:80 -v $volume:/data --pull always ghcr.io/huggingface/text-embeddings-inference:cuda-1.9-grpc --model-id $model
grpcurl -d '{"inputs": "What is Deep Learning"}' -plaintext 0.0.0.0:8080 tei.v1.Embed/Embed
Local install
Apple Silicon (Homebrew)
On Apple Silicon (M1/M2/M3/M4), you can install a prebuilt binary via Homebrew:
brew install text-embeddings-inference
Then launch Text Embeddings Inference with Metal acceleration:
model=Qwen/Qwen3-Embedding-0.6B
text-embeddings-router --model-id $model --port 8080
CPU
You can also opt to install text-embeddings-inference locally.
First install Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Clone the repository and enter its directory.
git clone https://github.com/huggingface/text-embeddings-inference.git
cd text-embeddings-inference
Then run:
# On x86 with ONNX backend (recommended)
cargo install --path router -F ort
# On x86 with Intel backend
cargo install --path router -F mkl
# On M1 or M2
cargo install --path router -F metal
Source builds use native CPU optimizations by default. Build on the machine that will run TEI, or on a CPU with compatible instruction sets. To disable the repository's native CPU flags when building for other CPUs of the same target architecture, use the following command.
RUSTFLAGS='' cargo install --path router -F ort
This does not cross-compile the application or change the requirements of prebuilt backend libraries.
You can now launch Text Embeddings Inference on CPU with:
model=Qwen/Qwen3-Embedding-0.6B
text-embeddings-router --model-id $model --port 8080
Note: on some machines, you may also need the OpenSSL libraries and gcc. On Linux machines, run:
sudo apt-get install libssl-dev gcc -y
CUDA
GPUs with CUDA compute capabilities < 7.5 are not supported (V100, Titan V, GTX 1000 series, ...).
Make sure you have CUDA and the NVIDIA drivers installed. NVIDIA drivers on your device need to be compatible with CUDA version 12.2 or higher. You also need to add the NVIDIA binaries to your path:
export PATH=$PATH:/usr/local/cuda/bin
Then run the following (might take a while as it needs to compile the CUDA kernels):
# On Turing GPUs (T4, RTX 2000 series ... )
cargo install --path router -F candle-cuda-turing
# On Ampere, Ada Lovelace, Hopper and Blackwell
cargo install --path router -F candle-cuda
You can now launch Text Embeddings Inference on GPU as follows:
model=Qwen/Qwen3-Embedding-0.6B
text-embeddings-router --model-id $model --port 8080
Docker
You can build the CPU container with Docker as:
docker build -f Dockerfile .
To build the CUDA containers, you need to know the compute cap of the GPU you will be using at runtime, to build the image accordingly:
# Get submodule dependencies
git submodule update --init
# Example for Turing (T4, RTX 2000 series, ...)
runtime_compute_cap=75
# Example for Ampere (A100, ...)
runtime_compute_cap=80
# Example for Ampere (A10, ...)
runtime_compute_cap=86
# Example for Ada Lovelace (RTX 4000 series, ...)
runtime_compute_cap=89
# Example for Hopper (H100, ...)
runtime_compute_cap=90
# Example for Blackwell (B200, GB200, ...)
runtime_compute_cap=100
# Example for Blackwell (GeForce RTX 50X0, RTX PRO 6000, ...)
runtime_compute_cap=120
# Example for Blackwell GB10 (DGX Spark)
runtime_compute_cap=121
docker build . -f Dockerfile-cuda --build-arg CUDA_COMPUTE_CAP=$runtime_compute_cap
ARM64 / aarch64
CPU-only (Apple Silicon, Ampere, Graviton)
For ARM64 hosts without NVIDIA GPUs, use the CPU Dockerfile. Inference runs on CPU cores only (no Metal/MPS support via Docker).
docker build . -f Dockerfile-arm64 --platform=linux/arm64
CUDA on ARM64 (DGX Spark, Jetson)
For ARM64 hosts with NVIDIA GPUs, build Dockerfile-cuda with the appropriate compute
capability and --platform linux/arm64:
# DGX Spark (GB10, sm_121)
docker build . -f Dockerfile-cuda \
--build-arg CUDA_COMPUTE_CAP=121 \
--platform linux/arm64
# Future ARM64 + Blackwell devices (sm_120)
docker build . -f Dockerfile-cuda \
--build-arg CUDA_COMPUTE_CAP=120 \
--platform linux/arm64
AMD Instinct GPUs (ROCm)
TEI supports AMD Instinct GPUs (MI200, MI300 series) via ROCm.
model=BAAI/bge-base-en-v1.5
volume=$PWD/data
docker run \
--device /dev/kfd --device /dev/dri \
--group-add video \
--ipc=host \
-p 8080:80 \
-v $volume:/data \
--pull always \
ghcr.io/huggingface/text-embeddings-inference:rocm-latest \
--model-id $model --dtype bfloat16
For full setup instructions, see the AMD Instinct GPU guide.