在macOS上用Docker部署Text Embedding Inference

11 次阅读

Text Embeddings Inference(TEI)是 Hugging Face 提供的高性能文本向量推理服务,适合把 BERT、E5、BGE、Qwen Embedding 等模型封装成 HTTP API,为语义搜索、RAG、知识库检索、文本相似度计算等应用提供统一的 Embedding 服务。官方文档目前提供 CPU 和多种 NVIDIA GPU 架构对应的容器,同时支持 ARM64 CPU 镜像。Hugging Face+1

对于 macOS 用户而言,Docker 部署 TEI 的重点并不是直接使用 NVIDIA GPU,而是根据 Mac 的处理器架构选择合适的 CPU 镜像。尤其是 Apple Silicon 设备,需要注意 Docker Desktop 虚拟化环境与 ARM64 镜像之间的关系。

macOS部署Text Embeddings Inference前的准备

开始操作之前,需要准备以下环境:

  • macOS系统

  • Docker Desktop

  • 可访问 Hugging Face Hub 的网络环境

  • 足够的磁盘空间

  • 一个兼容 TEI 的 Embedding 模型

如果使用 Apple Silicon Mac,例如 M1、M2、M3、M4 系列,通常属于 ARM64/aarch64 架构。可以通过终端查看:

Bash
uname -m

如果输出:

arm64

说明当前系统为 Apple Silicon 架构。

Intel Mac 通常会输出:

x86_64

两种架构对应的 TEI CPU 镜像并不完全相同。Hugging Face 当前提供了 cpu-1.9 和 cpu-arm64-1.9 等 CPU 镜像,其中 ARM64 镜像专门面向 aarch64 环境。Hugging Face

安装并检查Docker Desktop

macOS 上最简单的 Docker 环境是 Docker Desktop。

安装完成后,可以执行:

Bash
docker --version

然后进一步确认 Docker Engine 正常工作:

Bash
docker run --rm hello-world

如果能够正常看到 Docker 的欢迎信息,就说明 Docker Desktop 已经可以使用。

还可以查看 Docker 当前默认架构:

Bash
docker info

如果是 Apple Silicon Mac,建议优先使用 ARM64 容器镜像,这样可以减少不必要的架构转换。

选择适合macOS的TEI镜像

这一点是整个部署过程中最容易出错的地方。

macOS 本身并不能像 Linux + NVIDIA GPU 那样直接通过 Docker 使用 NVIDIA CUDA。Apple Silicon 的 GPU 也不能通过 --gpus all 的方式直接映射给 TEI。

因此,在普通 Mac 上进行 Docker 部署时,建议先按照 CPU 模式运行。

Apple Silicon 可以使用:

ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9

Intel Mac 可以使用:

ghcr.io/huggingface/text-embeddings-inference:cpu-1.9

官方支持列表明确列出了 CPU x86_64 和 CPU aarch64 对应的镜像。Hugging Face

如果只是本地开发、验证 RAG 流程或者搭建个人知识库,CPU 模式已经能够满足很多轻量级场景。

创建模型缓存目录

Embedding 模型第一次启动时通常需要从 Hugging Face Hub 下载模型文件。

可以提前建立一个数据目录:

Bash
mkdir -p ~/tei-data

进入工作目录:

Bash
cd ~/tei-data

也可以单独创建一个项目目录:

Bash
mkdir -p ~/docker/tei
cd ~/docker/tei
mkdir data

之后将 data 映射到容器中的 /data:

Bash
-v "$PWD/data:/data"

这样做的好处是模型下载完成后会保存在宿主机目录中。重新创建容器时,可以复用已经下载的模型文件,而不需要每次重新下载。Hugging Face 官方 Quick Tour 也推荐通过 volume 持久化模型权重。Hugging Face

使用Docker启动TEI

以 Apple Silicon Mac 为例,可以直接执行:

Bash
docker run --name tei 
  -p 8080:80 
  -v "$PWD/data:/data" 
  --pull always 
  ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9 
  --model-id Qwen/Qwen3-Embedding-0.6B

这里使用的是 Qwen/Qwen3-Embedding-0.6B。

该模型属于目前 TEI 支持的 Qwen3 Embedding 系列,官方支持模型列表中也包含 Qwen3-Embedding-0.6B。Hugging Face

如果是 Intel Mac,则可以调整镜像:

Bash
docker run --name tei 
  -p 8080:80 
  -v "$PWD/data:/data" 
  --pull always 
  ghcr.io/huggingface/text-embeddings-inference:cpu-1.9 
  --model-id Qwen/Qwen3-Embedding-0.6B

首次启动需要下载模型,因此启动速度可能明显慢于后续启动。

查看TEI容器启动状态

容器启动以后,可以使用:

Bash
docker ps

正常情况下可以看到类似:

CONTAINER ID   IMAGE                                                PORTS
xxxxxx         ghcr.io/huggingface/text-embeddings-inference:...   0.0.0.0:8080->80/tcp

如果容器没有正常运行,可以查看日志:

Bash
docker logs tei

实时查看日志:

Bash
docker logs -f tei

模型首次加载过程中可能需要一定时间,不建议看到容器刚启动就立即判断服务异常。

检查TEI健康状态

TEI启动之后,可以通过 HTTP 请求测试服务。

例如:

Bash
curl http://127.0.0.1:8080/health

如果服务正常,通常可以获得健康检查结果。

也可以直接请求 Embedding 接口:

Bash
curl 127.0.0.1:8080/embed 
  -X POST 
  -H "Content-Type: application/json" 
  -d '{"inputs":"Docker是一种常用的容器化技术"}'

TEI 官方提供了 /embed 接口用于文本向量生成,同时支持一次请求传递多个文本。Hugging Face

批量请求示例:

Bash
curl 127.0.0.1:8080/embed 
  -X POST 
  -H "Content-Type: application/json" 
  -d '{"inputs":["苹果电脑","Docker容器","文本向量模型"]}'

批量处理对于知识库导入尤其有价值,可以减少客户端频繁建立请求所带来的额外开销。

使用Python调用TEI

如果你的应用本身使用 Python,可以直接通过 HTTP API 调用。

最简单的方式是使用 requests:

Python
运行
import requests

url = "http://127.0.0.1:8080/embed"

payload = {
    "inputs": "如何使用Docker部署文本向量模型?"
}

response = requests.post(url, json=payload)

response.raise_for_status()

embedding = response.json()

print(embedding)

如果只想查看向量维度,可以进一步处理返回结果:

Python
运行
import requests

response = requests.post(
    "http://127.0.0.1:8080/embed",
    json={"inputs": "Docker部署TEI"}
)

response.raise_for_status()

result = response.json()

print("向量维度:", len(result[0]))

具体返回结构会随着客户端处理方式和 TEI 版本有所差异,因此实际开发时建议以当前部署版本的 API 返回值为准。

Hugging Face 官方也提供 huggingface_hub.InferenceClient 方式访问 TEI 服务。Hugging Face

例如:

Python
运行
from huggingface_hub import InferenceClient

client = InferenceClient()

embedding = client.feature_extraction(
    "What is deep learning?",
    model="http://localhost:8080/embed"
)

print(embedding)

macOS上如何选择Embedding模型

模型选择直接影响内存占用、启动时间、推理速度和向量质量。

对于 Mac 本地部署,通常不建议一开始就选择参数量非常大的 Embedding 模型。

例如:

Qwen/Qwen3-Embedding-0.6B

属于比较适合本地测试的选择。

TEI 当前支持的模型类型包括 BERT、XLM-RoBERTa、MPNet、ModernBERT、Qwen2、Qwen3、Gemma3、Mistral 等。官方支持列表同时列出了不同模型规模以及对应的模型 ID。Hugging Face

如果主要处理中文内容,还应该关注模型的多语言能力,而不能只看模型参数量。

例如:

intfloat/multilingual-e5-large-instruct

也是 TEI 支持的模型之一。Hugging Face

实际选型时,可以根据以下几个因素考虑:

需求关注点
本地开发模型体积和启动速度
中文知识库中文及多语言表现
多语言检索多语言Embedding能力
大规模数据导入批处理吞吐量
生产环境并发能力、延迟和资源成本
RAG系统检索效果与向量维度

Docker资源设置对性能的影响

macOS上的Docker Desktop运行在虚拟化环境中,因此容器可用资源并不完全等于 Mac 的物理资源。

可以在 Docker Desktop 的资源设置中检查 CPU 和内存分配。

如果给 Docker 分配的内存过低,大模型加载时可能出现:

Out of memory

或者容器直接退出。

对于较小的 Embedding 模型,可以从较低资源配置开始测试,然后根据实际情况调整。

查看容器资源使用情况:

Bash
docker stats tei

可以观察:

  • CPU使用率

  • 内存使用量

  • 内存占用比例

  • 网络流量

如果发现 CPU 长时间处于较高使用率,同时请求延迟明显增加,可以考虑降低单次请求的文本数量,或者换用参数规模更小的模型。

Apple Silicon为什么不能直接使用--gpus all

很多 Linux Docker 教程会使用:

Bash
docker run --gpus all ...

但这个参数主要用于 NVIDIA GPU 容器环境。

TEI 官方的 GPU 部署说明要求使用相应的 NVIDIA GPU、驱动和 NVIDIA Container Toolkit;当前 CUDA 容器支持的是相应 NVIDIA 架构。Hugging Face

Apple Silicon 的 GPU 并不属于这种 NVIDIA CUDA 环境,因此在普通 Mac 上照搬 Linux GPU 命令通常没有意义。

对于 Mac 本地 Docker 部署,更稳妥的方式是:

macOS
  ↓
Docker Desktop
  ↓
Linux容器
  ↓
TEI CPU镜像
  ↓
Embedding模型
  ↓
HTTP API

如果核心需求是充分利用 Apple GPU 加速,则需要考虑原生 macOS 推理方案,而不是简单地给 TEI Docker 容器添加 --gpus all。

事实上,Hugging Face 官方还提供了本地 CPU 模式,并针对 M1、M2 机器提供 Metal 构建选项,这说明 Apple Silicon 原生环境和 Docker CPU 容器属于不同的部署路径。Hugging Face

解决Docker架构不匹配问题

如果启动容器时出现类似:

no matching manifest for linux/arm64

通常说明当前镜像没有对应的 ARM64 manifest。

可以先检查:

Bash
docker image inspect ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9

也可以查看当前系统:

Bash
uname -m

对于 Apple Silicon,优先选择:

cpu-arm64

镜像。

不建议在没有明确需求的情况下强制使用:

Bash
--platform linux/amd64

虽然 Docker Desktop 可以借助虚拟化运行 x86_64 容器,但这会增加架构转换开销。对于需要持续进行 Embedding 推理的服务,原生 ARM64 CPU 镜像通常更合适。

模型下载失败怎么处理

第一次启动时,TEI需要从 Hugging Face Hub 获取模型。

如果日志出现网络连接、模型下载或者权限相关错误,可以先检查:

Bash
docker logs tei

如果模型是公开模型,通常不需要额外认证。

如果模型属于 gated model 或 private repository,则需要提供具有访问权限的 Hugging Face Token。官方文档建议使用 HF_TOKEN 环境变量。Hugging Face

例如:

Bash
export HF_TOKEN="你的Token"

然后:

Bash
docker run --name tei 
  -e HF_TOKEN="$HF_TOKEN" 
  -p 8080:80 
  -v "$PWD/data:/data" 
  ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9 
  --model-id your-org/your-private-model

不要把 Token 直接写进 Dockerfile,也不要提交到 Git 仓库。

模型已经下载后如何离线运行

对于网络受限环境,可以提前下载模型,然后挂载到容器中。

TEI 官方文档支持将本地模型目录映射到容器,并将 --model-id 指向容器内部路径。Hugging Face

例如模型目录位于:

~/models/gte-model

可以运行:

Bash
docker run --name tei 
  -p 8080:80 
  -v "$HOME/models/gte-model:/data/model" 
  ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9 
  --model-id /data/model

这种方式适合内网开发环境、重复部署环境以及需要固定模型版本的项目。

固定模型版本提高部署稳定性

直接使用:

Bash
--model-id Qwen/Qwen3-Embedding-0.6B

可以让 TEI 从 Hugging Face Hub 获取对应模型。

如果希望部署结果更加可控,可以进一步指定模型 revision。TEI 的命令行参数支持通过 --revision 指定模型的具体 revision、分支或 commit。Hugging Face

例如:

Bash
--model-id Qwen/Qwen3-Embedding-0.6B 
--revision main

对于正式项目,更建议固定到经过验证的具体版本,而不是让生产环境始终跟随模型仓库的最新变化。

使用Docker Compose管理TEI

如果项目中除了 TEI 之外还有向量数据库、后端 API 等服务,Docker Compose 会更加方便。

创建 compose.yml:

YAML
services:
  tei:
    image: ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9
    container_name: tei
    ports:
      - "8080:80"
    volumes:
      - ./data:/data
    command:
      - --model-id
      - Qwen/Qwen3-Embedding-0.6B

启动:

Bash
docker compose up -d

查看状态:

Bash
docker compose ps

查看日志:

Bash
docker compose logs -f tei

停止服务:

Bash
docker compose down

使用 Compose 后,模型、端口和 volume 配置都可以写入项目配置文件,后续重新部署更加方便。

常见问题排查

容器启动后立即退出

首先执行:

Bash
docker ps -a

找到 TEI 容器,然后查看:

Bash
docker logs tei

重点关注模型加载失败、内存不足、架构不匹配和参数错误。

8080端口已经被占用

如果出现端口冲突,可以修改宿主机端口:

Bash
docker run 
  -p 8081:80 
  ...

之后通过:

http://127.0.0.1:8081

访问服务。

模型下载很慢

模型权重通常只需要第一次下载。

确保已经挂载:

Bash
-v "$PWD/data:/data"

并检查 data 目录是否真正产生模型文件。

Embedding请求响应很慢

CPU模式下,推理性能受到模型规模、文本长度、Docker资源配置以及批处理方式影响。

可以先使用较小模型进行测试,同时避免一次发送大量超长文本。

对于知识库场景,可以在应用层先进行合理的文本切分,再批量调用 /embed。

返回模型不支持相关错误

TEI并不是任意 Hugging Face 模型都可以直接加载。官方维护了兼容的模型类型和模型列表,部署之前最好确认目标模型属于 TEI 支持范围。Hugging Face

TEI 的 --model-id 参数也要求模型具备相应的 TEI 兼容配置,或者提供符合要求的本地模型目录。Hugging Face

macOS Docker部署TEI的完整流程

如果只需要快速搭建一个本地 Embedding API,可以按照下面的顺序执行:

Bash
uname -m

确认机器架构。

然后创建目录:

Bash
mkdir -p ~/docker/tei/data
cd ~/docker/tei

Apple Silicon Mac 使用 ARM64 镜像:

Bash
docker run --name tei 
  -p 8080:80 
  -v "$PWD/data:/data" 
  --pull always 
  ghcr.io/huggingface/text-embeddings-inference:cpu-arm64-1.9 
  --model-id Qwen/Qwen3-Embedding-0.6B

检查容器:

Bash
docker ps

查看日志:

Bash
docker logs -f tei

测试 Embedding:

Bash
curl 127.0.0.1:8080/embed 
  -X POST 
  -H "Content-Type: application/json" 
  -d '{"inputs":"这是一个Docker Embedding测试"}'

如果能够正常返回向量,就说明整个部署链路已经建立完成。

TEI在RAG项目中的应用方式

完成部署后,TEI可以作为独立的 Embedding 服务存在。

典型的 RAG 架构可以设计成:

用户问题
   ↓
应用服务器
   ↓
TEI /embed
   ↓
生成Query向量
   ↓
向量数据库
   ↓
召回相关文档
   ↓
大语言模型
   ↓
生成最终回答

文档入库时也可以使用相同的 TEI:

原始文档
   ↓
文本清洗
   ↓
Chunk切分
   ↓
TEI批量Embedding
   ↓
向量数据库

这种设计的一个重要优势是把 Embedding 模型从业务代码中独立出来。以后更换模型时,只需要调整 TEI 服务配置,业务系统仍然可以通过统一的 HTTP 接口进行调用。

如果应用规模扩大,还可以将本地 macOS 上验证过的模型和 API 配置迁移到具备 GPU 的 Linux 服务器。生产环境的硬件选择则可以按照 TEI 官方支持的 CPU 或 NVIDIA GPU 架构重新配置。Hugging Face

对于 Mac 用户而言,Docker 部署 Text Embeddings Inference 最关键的是正确理解硬件边界:Apple Silicon 可以运行 ARM64 CPU 版 TEI,但不能把 Linux/NVIDIA CUDA 教程中的 GPU 参数原样套用到 Mac 上。先使用一个体积适中的兼容模型完成 /embed API 验证,再根据实际的 RAG 数据量、并发请求和延迟要求调整模型及资源配置,通常能更快建立稳定的本地 Embedding 服务。