Byzer-LLM 集成 LlamaIndex 支持

背景

如果你单纯的用llama_index, langchain之类的开发应用,看着Demo简单,但其实你真要上生产,是需要自己准备基础设施的,比如向量存储,全文检索,模型部署等,这部分工作其实是最麻烦的。

你可能会argue说模型这块他们也都做了支持,比如他们也可以启动一个vLLM然后带上私有模型。不过这种直接在应用里内嵌一个模型更多的是在开发阶段使用(实际上也合适,你的开发机大概率带不起来),实际生产其实不太可能这么用,大模型的部署一定是独立的机器或者集群,需要解决诸如多模型部署,SaaS/开源混合,多机部署等问题。

Byzer-Agent/Byzer-LLM/Byzer-Retrieval 和这些框架不同的是,他提供了一个完整的基础设施,覆盖了从大模型友好的存储到大模型自身的部署和serving,再到分布式agent应用开发框架。llama_index/langchain之类的其实属于 Byzer-Agent里的一个业务友好的库。

不过要能够在 Byzer-Agent里方便的使用 llama_index/langchain ,需要解决的一个问题就是让他们能够访问集成 Byzer-Retrieval/Byzer-LLM。

比如 llama_index 要能顺利运行起来,其实需要如下存储:

1. VectorStore

2. DocStore

3. IndexStore

我们使用 Byzer-Retrieval 统一支持了上面三种存储,满足了llama_index对存储的需求。

大模型侧则需要:

1. Embedding

2. Chat

3. Rerank

我们使用了 Byzer-LLM 支持 llama_index 对大模型的求。

现在,我们来看看怎么使用加持了 Byzer-Retrieval/Byzer-LLM 的llama_index。

构建索引

首先初始化 Byzer-Retrieval/Byzer-LLM:

code_search_path=["/home/winubuntu/softwares/byzer-retrieval-lib/"]
env_vars = {"JAVA_HOME": "/home/winubuntu/softwares/jdk-21",
            "PATH":"/home/winubuntu/softwares/jdk-21/bin:/home/winubuntu/.cargo/bin:/usr/local/cuda/bin:/home/winubuntu/softwares/byzer-lang-all-in-one-linux-amd64-3.1.1-2.3.2/jdk8/bin:/home/winubuntu/miniconda3/envs/byzerllm-dev/bin:/home/winubuntu/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"}


import os
os.environ["RAY_DEDUP_LOGS"] = "0" 


import ray
from byzerllm.utils.retrieval import ByzerRetrieval
from byzerllm.utils.client import ByzerLLM,Templates


ray.init(address="auto",namespace="default",ignore_reinit_error=True,
                 job_config=ray.job_config.JobConfig(code_search_path=code_search_path,
                                                      runtime_env={"env_vars": env_vars})
                 )  
# 设置 Qwen 客户端,参数
model_name = "qianwen_chat"
llm = ByzerLLM()
llm.setup_template(model=model_name,template="auto")
llm.setup_default_emb_model_name("emb")
llm.setup_default_model_name(model_name)
llm.setup_extra_generation_params(model_name,extra_generation_params={
    "temperature":0.01,
    "top_p":0.99
})


# 启动存储引擎,如果没有,则新启动一个
retrieval = ByzerRetrieval()
retrieval.launch_gateway() 
if not retrieval.is_cluster_exists("byzerai_store"):
    builder = retrieval.cluster_builder()
    builder.set_name("byzerai_store").set_location("/tmp/byzerai_store").set_num_nodes(2).set_node_cpu(0.1).set_node_memory("3g")
    builder.set_java_home(env_vars["JAVA_HOME"]).set_path(env_vars["PATH"]).set_enable_zgc()
    builder.start_cluster()

我们提前启动了一个 通义千问的SaaS的模型,所以在上面的代码我们只需要指定下模型的名字就可以连接。如果你忘记了怎么在Byzer-LLM中启动一个SaaS模型或者私有模型,参考这篇文章:

Byzer-LLM 支持同时开源和SaaS版通义千问

其次,我们连接一个 Byzer-Retrieval的存储集群,如果这个集群没人提前设置过的话,那么可以实时启动一个,比如上上面的例子里,我们会启动拥有两个节点,每个节点用 0.1块CPU(支持CPU Vector API计算向量相似度,嗷呜,有点拗口),每个节点占用 3G 内存的存储集群。

到目前为止,我们存储和模型都准备好了,可以用llama_index开始构建索引了:

from llama_index import SimpleDirectoryReader
from llama_index.node_parser import SentenceSplitter
from llama_index import SimpleDirectoryReader, VectorStoreIndex, ServiceContext
from llama_index import Document
from byzerllm.apps.llama_index import get_service_context,get_storage_context


service_context = get_service_context(llm)
storage_context = get_storage_context(llm,retrieval)


documents = SimpleDirectoryReader("/home/winubuntu/projects/jupyter-workspace/H/jupyter-workspace/data").load_data()
node_parser = SentenceSplitter(chunk_size=1024, chunk_overlap=20)


nodes = node_parser.get_nodes_from_documents(
    documents, show_progress=True
)
index = VectorStoreIndex(nodes=nodes, storage_context=storage_context, service_context=service_context)
index

我们通过 Byzer-LLM 提供的 get_service_context 和 get_storage_context 获得两个 context, 然后就可以直接读取指定目录里所有的文件,进行索引构建了(全文索引+向量索引),构建完成后,我们来看看怎么使用这些索引。

查询

你可以打开另外一个脚本,然后按下面的方式去使用:

from llama_index import VectorStoreIndex


index = VectorStoreIndex.from_vector_store(vector_store = storage_context.vector_store,service_context=service_context)
query_engine = index.as_query_engine()
response = query_engine.query("gluten 是什么?")
print(type(response))
print(response)
# Gluten是一个基于Spark插件接口开发的项目,本质上是一个大型的Spark插件库。它不需要侵入Spark代码库,

这样一个标准的基于 llama_index 的 RAG应用就构建起来了。这个回答其实就是来源于我们刚才构建的索引。

总结

其实 llama_index做了大量对大模型和存储引擎的对接工作,但我觉得他应该好好聚焦在RAG业务策略上,比如对大模型的对接工作,完全可以交给 Byzer-LLM来完成,而对存储引擎的对接工作,因为用户终究会五花八门的使用各种可能已经存在的存储,这个工作可以完全交给langchain来做。

如果用户没有什么包袱,那么用 Byzer-LLM+Byzer-Retrieval + LlamaIndex 则可以完全屏蔽掉模型以及存储细节,专心在LlamaIndex选择适合自己业务场景的 RAG 策略即可。如果未来需求进一步复杂,需要分布式多Agent协作,则可以把这些基于LlamaIndex的代码很方便的迁移到 Byzer-Agent 框架里去。

顺带说一说,Agent 一定是重开发的,尤其是多Agent 协作,不要被花里胡哨的可视化Agent Workflow 迷了眼。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值