EmbedAnything
Rust 编写的多模态向量 embedding 管道,无需 PyTorch 即可实现高速推理
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
Rust 编写的多模态向量 embedding 管道,无需 PyTorch 即可实现高速推理
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象你经营着一个不断扩张的知识库——PDF 文档、产品手册、内部 Wiki、技术博客,用户期待在任何时候都能用自然语言找到精确答案。传统的做法是:把文档切块(chunking)、调用 embedding 模型生成向量、存入向量数据库、等待查询。整个过程动辄数分钟,尤其在处理大型 PDF 或批量文档时,开发者的等待焦虑几乎成了日常。
EmbedAnything 解决的就是这个痛点。这是一个用 Rust 编写的多模态 embedding 管道,以「向量化即服务」的思路,将文档解析、模型推理、向量索引三大环节解耦,通过 Rust 原生的多线程与零成本抽象,实现了远高于 Python 生态同类工具的吞吐量。更重要的是,它彻底摆脱了对 PyTorch 的依赖,CPU 环境下也能高效运行。

图1:EmbedAnything 官方项目 Logo
向量检索(Vector Retrieval)是 RAG(检索增强生成)系统的核心基础设施。随着大模型(LLM)能力不断增强,越来越多的企业开始在内部知识库、客服机器人、代码搜索等场景中部署 RAG 方案。一个 RAG 系统的效果,80% 取决于 embedding 的质量与检索的效率。
然而,现有的 embedding 工具普遍存在以下问题:
EmbedAnything 由 StarlightSearch 团队开发,针对上述问题给出了系统性答案:Rust 内存安全 + Candle 轻量推理引擎 + 多源适配器架构。项目于 2024 年 3 月开源,截至目前已获得超过 1,200 颗 GitHub Stars,并与 Elastic、Weaviate、SingleStore、Milvus 等主流向量数据库厂商建立了深度合作。
EmbedAnything 的设计哲学可以概括为「一个入口,多种输出」。用户只需学会一套 API,就能对文本、PDF、图片、音频、Web 页面乃至 AWS S3 存储桶中的文件进行统一的向量化处理。
项目内置了完善的多格式文件解析器,覆盖主流场景:
| 格式 | 支持情况 | 说明 |
|---|---|---|
| 纯文本(TXT/MD) | ✅ 完整 | 直接分块 + embedding |
| ✅ 完整 | 文本提取 + 可选 OCR(text_ocr.py) | |
| 图片(JPG/PNG) | ✅ 完整 | 通过 CLIP 模型编码 |
| 音频(WAV/MP3) | ✅ 完整 | 通过 Whisper 模型转录后 embedding |
| Web 页面 | ✅ 完整 | 内置 web 爬虫 + 清洗 |
| AWS S3 对象 | ✅ 完整 | 直接读写 S3,无需下载到本地 |
这是 EmbedAnything 最具差异化的特性。传统 embedding 管道的瓶颈在于:文档必须全部处理完毕,才能开始生成向量。而 EmbedAnything 通过 Rust MPSC(多生产者单消费者)通道,将文档解析与向量生成解耦为独立线程。

图2:Vector Streaming 架构——文档解析与向量生成并行执行
这样做有两个显著好处:其一,延迟大幅降低,第一段文本的向量几乎可以立即产出,无需等待整个文件处理完毕;其二,内存占用稳定,向量直接流式写入向量数据库,不会出现大量中间结果堆积在内存中导致 OOM 的问题。项目官方博客详细记录了这一设计决策的技术细节。
项目基于三大推理后端构建:
支持的模型类型覆盖了向量检索的主流范式:
all-MiniLM-L12-v2EmbedAnything 提供了多种切块策略,比简单的固定长度切块更「聪明」:

图3:推理速度基准测试——EmbedAnything vs 其他框架
图注:在 500 份 PDF 的测试集上,EmbedAnything 的 CPU 推理速度显著领先 Python 生态方案。
理解 EmbedAnything 的代码结构,需要从它的 Cargo Workspace 入手。项目由四个核心 crate 组成:
EmbedAnything (Workspace Root)
├── processors/ # 文件解析层:PDF、文本、图片、音视频、Web、S3
├── rust/ # 核心 embedding 引擎:Candle + ONNX 推理
├── python/ # Python 绑定层(通过 maturin 编译为 .so)
└── server/ # OpenAI 兼容 API 服务(端口 8080)
processors-rs 是统一的内容提取抽象层。它为每种文件格式定义了标准化的解析接口,返回统一的 ProcessedContent 结构体,屏蔽了底层格式差异。其中 file_loader.rs 是总调度器,根据文件扩展名路由到对应的解析器;text_loader.rs 处理文本,s3_loader.rs 处理 AWS S3 对象,file_processor/ 子目录则容纳了各格式的专用处理器。
值得注意的是,项目集成了 Mozilla 的 pdf-extract 库来完成 PDF 文本提取,在准确性上优于纯字符串匹配方案。
rust/src/ 是项目的性能核心所在。其目录结构如下:
models/:各类 embedding 模型的统一调用接口embeddings/:embedding 生成逻辑,包含 ONNX 与 Candle 两种后端的路由chunkers/:语义切块实现reranker/:重排序模型封装embeddings/ 目录下包含了大量适配器脚本(examples/ 目录下),例如:
clip.py:图片 embedding(CLIP 模型)colpali.py:多模态 PDF embedding(ColPali)colbert.py:Late-interaction 检索(ColBERT)splade.py:稀疏向量 embeddingmodel2vec.py:轻量 embedding每个适配器都遵循「加载模型 → 配置参数 → 批量推理 → 返回向量」的统一范式,用户切换模型只需修改一行 model_id 参数。
python/Cargo.toml 配置了 maturin 构建系统,将 Rust 核心编译为 Python 可直接调用的扩展模块(embed_anything._embed_anything)。这使得 Python 开发者可以用熟悉的 pip 安装方式使用高性能 Rust 库,同时享受原生 Rust 的性能优势。
maturin 的热重载特性也使得开发阶段可以快速迭代 Rust 代码,无需每次重新编译整个 Python 环境。
server/ 是一个用 Rust 编写的轻量 HTTP 服务,监听 0.0.0.0:8080,提供以下端点:
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/embeddings | POST | OpenAI 兼容的 embedding 接口 |
/v1/pdf_embeddings/upload | POST | PDF 文件上传 + 向量化(multipart/form-data) |
/health_check | GET | 健康检查 |
这种设计让 EmbedAnything 可以直接作为微服务嵌入任何 RAG 架构,无需改变已有的调用代码。企业用户可以将 server 部署为独立容器,通过 REST API 供多个下游服务共享 embedding 能力。
项目提供了四套 Dockerfile,覆盖不同场景:
cargo-chef 多阶段构建,包含 Rust 所有依赖,体积较大虽然没有提供 docker-compose.yml,但用户可以基于 server.Dockerfile 自行编排。
EmbedAnything 提供两条安装路径,分别面向不同用户:
CPU 环境:
pip install embed-anything
GPU 环境(支持 ColPali 等特殊模型):
pip install embed-anything-gpu
最低 Python 版本要求 3.10,整个安装过程约 1-2 分钟(首次需编译 Rust 扩展)。
# 拉取预构建镜像
docker pull starlightsearch/embedanything-server
# 启动服务
docker run -p 8080:8080 starlightsearch/embedanything-server
服务启动后,通过 curl 调用 API:
curl -X POST http://localhost:8080/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"model": "sentence-transformers/all-MiniLM-L12-v2", "input": ["Hello world"]}'
以一份 PDF 文档为例,完整的 embedding 流程约 5 行代码:
from embed_anything import EmbeddingModel
# 加载模型
model = EmbeddingModel.from_pretrained_hf(
model_id="sentence-transformers/all-MiniLM-L12-v2"
)
# 配置切块参数
config = TextEmbedConfig(
chunk_size=1000,
batch_size=32,
splitting_strategy="semantic"
)
# 嵌入 PDF
data = embed_anything.embed_file("document.pdf", embedder=model, config=config)
# 输出向量
for item in data:
print(f"文本块: {item.text[:100]}...")
print(f"向量维度: {len(item.embedding)}")
生成的向量可直接写入 Milvus、Weaviate、Elastic 等向量数据库,构建完整的 RAG 检索管道。
客观地说,EmbedAnything 并非完美解决方案,以下几点值得潜在用户知悉:
第一,Python 包的二进制编译依赖 Rust 工具链。 虽然 pip install 自动完成编译,但国内网络环境下从源码编译 Rust 依赖耗时较长(首次约 10-30 分钟)。Docker 方式可以规避这一步骤,但增加了容器运维复杂度。
第二,Web UI 缺失。 项目完全以编程方式使用,没有提供图形化界面来预览 embedding 效果、调整切块参数或可视化向量分布。对于非技术用户,入门门槛相对较高。
第三,CUDA 镜像构建耗时。 server-cuda.Dockerfile 虽然功能完整,但首次构建需要从源码编译 CUDA 支持的 Candle,加上 sccache 缓存优化,总耗时仍在 15-30 分钟量级。
第四,与国产向量数据库的集成文档有限。 虽然支持 Milvus 和 Weaviate,但对于 Vearch、Tencent Vector DB 等国产方案,缺少开箱即用的适配器脚本,需要用户自行对接。
第五,模型生态的版本维护风险。 项目大量依赖 Hugging Face 上的第三方模型,这些上游模型更新可能导致 API 不兼容,需要用户自行锁定版本。
EmbedAnything 的出现折射出向量检索领域的几个重要趋势:
趋势一:Rust 正在重塑 AI 基础设施。 此前 AI 推理的高性能需求几乎被 CUDA/PyTorch 垄断,但随着 Candle、llama.cpp 等 Rust ML 库的成熟,越来越多对性能敏感的 AI 工具选择 Rust 作为核心语言。Rust 的内存安全性与零成本抽象,使得无需 PyTorch 也能写出高效推理代码。
趋势二:embedding 从单模型走向多范式融合。 单一的 dense embedding 已经无法满足生产级检索系统的精度需求。Hybrid Search(dense + sparse + reranker)正在成为新的标准。EmbedAnything 对 Splade、ColBERT、Reranker 的原生支持,正好顺应了这一趋势。
趋势三:向量处理管道化。 传统的「文件→向量→入库」批处理模式正在被流式管道取代。Vector Streaming 的设计让 embedding 可以与向量数据库写入并行执行,显著降低端到端延迟。
趋势四:embedding 服务化。 OpenAI 兼容 API 的提供意味着 embedding 能力可以作为一种独立服务被多个应用共享,这是企业级部署的重要一步。
目前,EmbedAnything 已与 Elastic、Weaviate、SingleStore、Milvus 四大主流向量数据库建立了正式合作,在各家的官方文档中均提供了集成指南。