You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效向ChromaDB导入百万级文档?

ChromaDB大规模文档导入:一次性导入vs批量添加优化方案

核心结论

直接用Chroma.from_documents一次性导入所有切分后的文档(内存允许的前提下),效率远高于多次调用add_documents。

为什么批量add会越来越慢?

  • Chroma每次调用add_documents时,除了生成嵌入向量,还要实时更新HNSW索引结构。随着数据库里的数据量增大,索引更新的计算开销会持续增长,导致每批导入的耗时越来越长。
  • 频繁的自动磁盘持久化操作,会累积IO开销,进一步拖慢导入速度。

基于GPU资源的优化方案

方案1:全量一次性导入(优先推荐)

如果你的内存能装下1200万份文档的原始文本+嵌入向量(按MiniLM-L6的384维嵌入计算,单条向量约1.5KB,1200万条总大小约18GB,加上原始文本的内存压力不大),直接全量导入是最快的方式:

# 先完成所有200万篇文章的切分
all_docs = text_splitter.create_documents(all_documents)

# 一次性创建Chroma库并导入所有文档
vectordb = Chroma.from_documents(
    documents=all_docs,
    embedding=embeddings,
    persist_directory=persist_directory,
    collection_metadata={"hnsw:space": "cosine"}
)
vectordb.persist()

这种方式下,Chroma会批量生成嵌入,一次性构建完整索引,避免了多次索引更新的额外开销,GPU的并行计算能力也能被充分利用。

方案2:优化批量导入流程(内存不足时)

如果内存无法容纳全量文档,需要分批次导入,可通过以下几点优化:

  • 增大批量大小:当前用41000的批次,可尝试提升到10万甚至20万(根据GPU显存和内存调整),减少索引更新的次数。
  • 延迟持久化:不要让Chroma每次添加后自动持久化,改为所有批次导入完成后统一调用persist(),降低磁盘IO频率。
  • 手动控制索引构建:先关闭自动索引更新,等所有数据导入完毕后再手动构建索引,避免中途多次更新索引的开销。

优化后的批量导入代码示例:

# 初始化空的Chroma库
vectordb = Chroma(
    embedding_function=embeddings,
    persist_directory=persist_directory,
    collection_metadata={"hnsw:space": "cosine"}
)

# 关闭自动索引更新,避免导入时实时更新
vectordb._collection.modify_collection(metadata={"hnsw:construction_ef": -1})

# 批量导入函数
def batch_process(documents_arr, batch_size):
    for i in range(0, len(documents_arr), batch_size):
        batch = documents_arr[i:i + batch_size]
        vectordb.add_documents(documents=batch)
        print(f"完成第 {i//batch_size +1} 批次导入")

# 先切分所有文档
all_docs = text_splitter.create_documents(all_documents)
batch_size = 100000  # 根据自身资源调整
batch_process(all_docs, batch_size)

# 所有数据导入完成后,手动构建索引
vectordb._collection.create_index()
# 最后统一持久化到磁盘
vectordb.persist()

额外优化点

  • 确认嵌入模型完全跑在GPU上:检查model_kwargs={"device": "cuda"}是否生效,可通过SentenceTransformer(model_path).device查看,避免模型 fallback 到CPU拖慢速度。
  • 预生成嵌入向量:如果内存足够,可先批量生成所有文档的嵌入向量,再导入Chroma,把嵌入生成和数据库导入分开,充分利用GPU并行能力:
# 预生成所有文档的嵌入向量
embeddings_list = embeddings.embed_documents([doc.page_content for doc in all_docs])

# 直接导入带预生成嵌入的文档
vectordb = Chroma.from_documents(
    documents=all_docs,
    embedding=embeddings,
    persist_directory=persist_directory,
    embeddings=embeddings_list
)

内容的提问来源于stack exchange,提问作者user23501561

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 23:48:15