跳到主要内容

智能体与检索框架

LlamaIndex 私有化部署:框架不吃显存,吃显存的是你挂在它后面的三个模型

llama-index-core 0.14.24 配 llama-index-workflows 2.23.3 是当下的正式线。把 embedding、reranker、LLM 三件套装进同一张卡,NexGPU 从 $0.193/卡·时 起,按秒计费。

先把定位说清楚:LlamaIndex 不是一组模型权重,而是 run-llama 维护的文档智能体与检索框架,MIT 协议,GitHub 上 51.8k star、8.0k fork,LlamaHub 上挂着 300 多个集成包。你搜到的「LlamaIndex 需要多大显存」,答案永远不在框架本身——它编排的是别人的模型。还有个小坑值得先记下:文档站已经从 docs.llamaindex.ai 整体 301 跳到 developers.llamaindex.ai,老教程里的链接点过去会落到新路径上,路径结构也换了。

当前的版本格局跟很多人印象里的不一样。Workflows 已经从 core 里彻底拆出来,走独立版本线 llama-index-workflows 2.23.3,导入路径是 from workflows import Workflow, step,llama_index.core.workflow 只是保持 API 稳定的兼容层。原来的 workflows-py 仓库并入了 run-llama/llama-agents 单体仓库,品牌叫 LlamaAgents;服务化的活交给 llama-agents-server 0.7.1 加 llamactl 命令行,而老的 llama-deploy 把 llama-index-core 锁在 0.14.0 以下,跟今天的 0.14.24 直接冲突,新项目别再从那条线起步。

私有化部署的全部工作量,本质上就是把三个默认值换掉。llama_index.core.settings 里 Settings.llm 的默认解析是 resolve_llm("default"),它会直接 new 一个 OpenAI() 并校验 key,失败就抛「Could not load OpenAI model」;Settings.embed_model 默认落到 BAAI/bge-small-en,一个纯英文模型;Settings.context_window 默认常量是 3900。把这三个换成本地 vLLM 端点、bge-m3 和你模型真实的上下文长度,LlamaIndex 就完全离线了——剩下的只是给这三个模型找一张显存够用的卡。

01 —

当前在维护的版本线

六个包,六条独立版本线,对不上号就会互相锁死

版本参数量显存上下文说明
llama-index 0.14.24元包,只有 4 个直接依赖框架 0GB,默认走 OpenAI APISettings.context_window 默认 3900pip install llama-index 的起步包,会顺带把 llama-index-llms-openai 0.7.10 和 llama-index-embeddings-openai 装进来。想完全离线,这个包反而不该装。
llama-index-core 0.14.24纯核心,要求 Python ≥3.10 且 <4.00GB,模型全部外挂由你注入的 LLM metadata 决定私有化部署的真正起点。Settings、节点解析、检索器、FunctionAgent 与 AgentWorkflow 都在这里,不含任何云端 LLM 依赖。
llama-index-workflows 2.23.3事件驱动运行时,可独立安装0GB,纯编排层状态按 run id + namespace 分区持久化已从 core 拆成独立版本线。支持 list[E] 的 fan-out/fan-in、@catch_error 兜住重试耗尽、快照回放续跑,agent 中途崩了不用从头再来。
llama-agents-server 0.7.1 / llama-agents-client 0.3.12Starlette + uvicorn 服务壳0GB,与推理进程分离流式输出、人在回路、run 持久化把任意 Workflow 包成 REST 服务,也能直接挂进你已有的 FastAPI 应用;配 llamactl 做 init/serve/deployments create 的完整链路。
LlamaIndex.TS 0.12.1(npm)TypeScript 实现,同为 MIT0GB,一般只做前端侧编排跟随所接模型Node 与 Edge 运行时的对等实现,版本线跟 Python 完全独立,覆盖面不如 Python 全;重检索逻辑建议还是留在 Python 侧。
llama-deploy 0.9.2(已被取代)依赖里锁死 llama-index-core <0.14.00GB仅支持旧版 Workflow 契约它的 core 上限和现在的 0.14.24 直接打架,装上就会把 core 降级。迁到 llama-agents-server 加 llamactl,这是官方在推的那条路。

02 —

按你实际要跑的模型选卡

显存花在 embedding、reranker、LLM 三件套上,框架一分不占

  • 只做灌库:批量 embedding + 重排,不跑生成

    RTX 3090 24GB$0.193/卡·时

    bge-m3 fp16 约 1.2GB、bge-reranker-v2-m3(5.68 亿参数)fp16 约 1.1GB,24GB 里剩下 20 多 GB 全能拿去堆 embed_batch_size,这是全站最便宜的算力单价。

  • 单卡跑完整本地栈:Qwen3-8B 生成 + bge-m3 检索 + 重排

    RTX 5090 32GB$0.723/卡·时

    Qwen3-8B 实际 81.9 亿参数,bf16 权重约 16.4GB,再叠两个检索模型的 2.3GB 就逼近 19GB,24GB 卡留给 KV cache 的余量太薄,32GB 才跑得开长上下文。

  • FunctionAgent 要稳定调工具:Qwen3-32B AWQ-INT4 + 32K 以上上下文

    RTX A6000 48GB$0.817/卡·时

    327.6 亿参数量化到 INT4 后权重落在 20GB 上下,48GB 能同时喂下长 KV cache 和几路并发;工具调用的成功率比 8B 级模型高一个台阶,多 agent 交接才不会卡死。

  • AgentWorkflow 多 agent 交接,32B 级模型跑 bf16 不量化

    A100 SXM4 80GB$1.088/卡·时

    Qwen3-32B 光 bf16 权重就是 65.5GB,只有 80GB 级显存放得下;handoff 会把上下文越滚越长,KV 余量必须一次留够,中途 OOM 会把整条 workflow 的 run 状态打断。

03 —

四步把 LlamaIndex 搬进自己的卡

从空实例到一个能对外提供 REST 接口的本地 RAG 智能体

  1. 01

    开实例,装最小可用的包集合

    在 NexGPU 控制台选 PyTorch 或 vLLM 预置镜像开机,SSH 进去。别装 llama-index 元包——它会把 OpenAI 的 LLM 和 embedding 依赖一起拖进来。直接从 core 起步,按需补集成包,用 uv 装能避开 300 多个包之间的版本回退。

    uv pip install "llama-index-core>=0.14.24" llama-index-llms-openai-like llama-index-embeddings-huggingface llama-index-postprocessor-flag-embedding-reranker llama-index-vector-stores-qdrant
  2. 02

    先把 vLLM 的 OpenAI 兼容端口拉起来

    LlamaIndex 不负责推理,它只是个 HTTP 客户端。先让模型跑起来,注意一定要开工具调用解析,否则 FunctionAgent 拿不到结构化的 tool_calls,只能退化成让模型自己吐 JSON。gpu-memory-utilization 留出余量,因为同一张卡上还要塞 bge-m3 和 reranker。

    vllm serve Qwen/Qwen3-8B --served-model-name qwen3-8b --max-model-len 32768 --gpu-memory-utilization 0.72 --enable-auto-tool-choice --tool-call-parser hermes --port 8000
  3. 03

    改掉那三个会让你踩坑的默认值

    OpenAILike 的 is_chat_model 和 is_function_calling_model 默认都是 False,context_window 默认继承 3900——三个开关不显式打开,你会得到一个既不会调工具、又把 32K 上下文截到 3900 的 agent。embedding 侧 device 虽然会自动推断到 CUDA,但 DEFAULT_EMBED_BATCH_SIZE 只有 10,不手动调大等于让 GPU 空转。

    from llama_index.core import Settings
    from llama_index.llms.openai_like import OpenAILike
    from llama_index.embeddings.huggingface import HuggingFaceEmbedding
    
    Settings.llm = OpenAILike(model="qwen3-8b", api_base="http://127.0.0.1:8000/v1", api_key="EMPTY", context_window=32768, is_chat_model=True, is_function_calling_model=True)
    Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-m3", device="cuda", embed_batch_size=64)
  4. 04

    建索引、起 agent、包成服务

    建查询引擎时记得把 similarity_top_k 从默认的 2 提上去——默认值只召回两个节点,中文长文档基本必漏。Memory 是现在的正统记忆类,ChatMemoryBuffer 已标记废弃。最后用 WorkflowServer 把 agent 包成带流式和人在回路的 REST 服务,其他服务用 llama-agents-client 调它就行。

    from llama_index.core.agent.workflow import FunctionAgent
    from llama_index.core.memory import Memory
    from llama_agents.server import WorkflowServer
    
    query_tool = index.as_query_engine(similarity_top_k=8, node_postprocessors=[reranker])
    agent = FunctionAgent(tools=[...], llm=Settings.llm, system_prompt="...")
    memory = Memory.from_defaults(session_id="u-1", token_limit=40000)
    
    server = WorkflowServer()
    server.add_workflow("rag", agent)

一次完整私有化验证的真实账单

算笔具体的账。一套两百万字的中文内规文档,第一步用 RTX 3090 24GB($0.193/卡·时)跑 bge-m3 灌库,embed_batch_size 调到 64,约 3 小时跑完全量索引:3 × 0.193 = $0.579。第二步换 RTX 5090 32GB($0.723/卡·时)挂 Qwen3-8B 做内部试用,每天开 8 小时、连开 5 天共 40 小时:40 × 0.723 = $28.92。索引、模型权重和向量库合计占 20GB 持久化存储,按 $0.414/GB·月 的中位价,一周约 20 × 0.414 × 7 ÷ 30 = $1.93。三项相加:0.579 + 28.92 + 1.93 ≈ $31.43,一周之内把 LlamaIndex 私有化的可行性彻底验证完。计费按秒计量、按小时计价,没有最低消费、没有开通费、不用提配额申请;实例一停,计算费用立刻停止,存储费用则会一直计到你把它销毁为止——所以验证跑完记得顺手清盘。

04 —

常见问题

LlamaIndex 本地部署到底需要多大显存?

框架本身是纯 Python 编排层,0GB 显存。真正吃显存的是你挂在它后面的三件套:bge-m3 fp16 约 1.2GB、bge-reranker-v2-m3 fp16 约 1.1GB,生成模型看你选谁——Qwen3-8B bf16 权重 16.4GB、Qwen3-32B bf16 权重 65.5GB、量化到 INT4 后 32B 大约落在 20GB。所以问题永远要拆成「我要跑哪个 LLM」。在 NexGPU 上你可以先用 RTX 3090 24GB($0.193/卡·时)把索引灌完,再按生成模型的实际尺寸换到 5090 32GB、A6000 48GB 或 A100 80GB,按秒计费,换卡不用重开一套账。

为什么我明明要用本地模型,却报「Could not load OpenAI model」?

因为 Settings.llm 的 getter 在你没赋值时会执行 resolve_llm("default"),这个分支硬编码去 new 一个 OpenAI() 并校验 api_key,校验不过就抛出那段星号包裹的错误。同理 Settings.embed_model 默认解析到 BAAI/bge-small-en。解决办法不是设一个假 key,而是在任何索引操作之前显式赋值 Settings.llm 和 Settings.embed_model。NexGPU 的 vLLM 预置镜像开机就能直接 serve 出 OpenAI 兼容端口,api_base 指过去、api_key 填 EMPTY 就完事了。

接上 vLLM 之后 FunctionAgent 就是不调工具,上下文还老被截断?

这是 OpenAILike 最典型的坑:它的 is_chat_model 和 is_function_calling_model 两个字段默认值都是 False,context_window 默认继承核心常量 3900。前者会让 LlamaIndex 认为模型不支持 function calling,于是不下发 tools 参数;后者会让 prompt helper 把你 32K 甚至 128K 的上下文硬截到 3900 token。三个参数在构造 OpenAILike 时全部显式写出来即可。另外 vLLM 侧也得带上 --enable-auto-tool-choice 和对应的 --tool-call-parser,两端都开通了链路才通——这套配置在 NexGPU 的 vLLM 镜像里改一行启动参数就能验证。

同样一份中文文档,为什么 LlamaIndex 的检索效果比预期差很多?

大概率同时踩了三个默认值。第一,HuggingFaceEmbedding 的默认模型是 BAAI/bge-small-en,纯英文训练,中文语料上召回会塌;换成 bge-m3 或 Qwen3-Embedding-0.6B(5.96 亿参数,bf16 约 1.2GB)立刻不一样。第二,DEFAULT_SIMILARITY_TOP_K 是 2,只召回两个节点,长文档必漏,实践中先提到 8 再交给 reranker 收敛。第三,DEFAULT_CHUNK_SIZE 是 1024 token、overlap 只有 20,中文场景下切分粒度往往需要重调。这些都是纯配置问题,租一张 RTX 3090 24GB 花不到一美元就能把几组参数对比着跑完。

LlamaIndex 和 LangChain 该怎么选?

定位差别很实在。LlamaIndex 的重心在文档:解析、切分、索引、检索、重排这条链路上的抽象最厚,官方自己的定位就是文档智能体与 OCR 平台,LlamaParse 覆盖 130 多种格式。编排层面,Workflows 走的是事件驱动——步骤是收事件、发事件的 async 函数,分支、循环、并行都是普通 Python,没有额外的图 DSL 要学,而且自带持久化状态和快照回放。如果你的主战场是「一堆非结构化文档 + 需要能续跑的长流程」,LlamaIndex 更顺手。两个框架都不吃显存,真正决定成本的是后面那台推理机——NexGPU 覆盖 51 个国家和地区、1,175 个已验证可租节点、75 种 GPU 型号,两套方案可以并排跑同一份语料做 A/B。

老项目里的 ServiceContext、ChatMemoryBuffer、llama-deploy 还能继续用吗?

都到了该迁的时候。ServiceContext 已被 Settings 取代,官方专门留了一份迁移指南;ChatMemoryBuffer、ChatSummaryMemoryBuffer、VectorMemory、SimpleComposableMemory 全部标记为废弃,新代码统一用 Memory.from_defaults(token_limit=...),它自带短期/长期记忆的 token 配比和溢出刷写;llama-deploy 因为把 llama-index-core 锁在 0.14.0 以下,装上会把你的 core 降级,应当迁到 llama-agents-server 加 llamactl。迁移最怕的是本地环境被依赖搅乱——在 NexGPU 开一台按秒计费的干净实例把新旧两套并行验证一遍,跑完即停,成本通常不到一杯咖啡。

开始使用 NexGPU

无论你是企业研发团队还是独立开发者,都可以在几分钟内跑起第一个任务。

注册即可浏览全网实时价格,无需绑定支付方式。