当前位置: 首页 > news >正文

LazyLLM 学习

参考文章:

https://blog.csdn.net/csdnstudent/article/details/151999341

https://blog.csdn.net/csdnstudent/article/details/151827710

LazyLLM github:

https://github.com/LazyAGI/LazyLLM

实现目标:

        给智能体一些pdf,通过问答形式了解书中知识,便于学习。

环境搭建

python下载

根据参考文章中内容,下载python 3.10

官网下载地址:https://www.python.org/downloads/windows/

选合适版本下载,直接执行安装,安装成功后在cmd中可以直接执行python。

环境搭建

win10环境,在对应文件夹运行:

python -m venv lazyllm-venv
cd lazyllm-venv
lazyllm-venv/bin/activate
pip3 install lazyllm -i https://pypi.tuna.tsinghua.edu.cn/simple

运行activate后进入虚拟环境,和docker的环境一样。

在虚拟环境中执行pip3安装依赖。

根据文档获取和设置对应key,本次测试使用通义千问。

获取通义千问的key

进入阿里大模型平台

https://bailian.console.aliyun.com

登录后,获取key,对应模型可以直接使用,不用开通。

实现原理

设置线上推理模型

base_url_http = "https://dashscope.aliyuncs.com/compatible-mode"
llm=OnlineChatModule(source='qwen', model="qwen-plus", stream=False,base_url=base_url_http)

文档路径:lazyllm-venv\Lib\site-packages

根据文档

class OnlineChatModule(metaclass=_ChatModuleMeta):"""Used to manage and create access modules for large model platforms currently available on the market. Currently, it supports openai, sensenova, glm, kimi, qwen, doubao and deepseek (since the platform does not allow recharges for the time being, access is not supported for the time being). For how to obtain the platform's API key, please visit [Getting Started](/#platform)Args:model (str): Specify the model to access (Note that you need to use Model ID or Endpoint ID when using Doubao. For details on how to obtain it, see [Getting the Inference Access Point](https://www.volcengine.com/docs/82379/1099522). Before using the model, you must first activate the corresponding service on the Doubao platform.), default is ``gpt-3.5-turbo(openai)`` / ``SenseChat-5(sensenova)`` / ``glm-4(glm)`` / ``moonshot-v1-8k(kimi)`` / ``qwen-plus(qwen)`` / ``mistral-7b-instruct-v0.2(doubao)`` .source (str): Specify the type of module to create. Options include  ``openai`` /  ``sensenova`` /  ``glm`` /  ``kimi`` /  ``qwen`` / ``doubao`` / ``deepseek (not yet supported)`` .base_url (str): Specify the base link of the platform to be accessed. The default is the official link.system_prompt (str): Specify the requested system prompt. The default is the official system prompt.stream (bool): Whether to request and output in streaming mode, default is streaming.return_trace (bool): Whether to record the results in trace, default is False.      Examples:>>> import lazyllm>>> from functools import partial>>> m = lazyllm.OnlineChatModule(source="sensenova", stream=True)>>> query = "Hello!">>> with lazyllm.ThreadPoolExecutor(1) as executor:...     future = executor.submit(partial(m, llm_chat_history=[]), query)...     while True:...         if value := lazyllm.FileSystemQueue().dequeue():...             print(f"output: {''.join(value)}")...         elif future.done():...             break...     print(f"ret: {future.result()}")...output: Hellooutput: ! How can I assist you today?ret: Hello! How can I assist you today?>>> from lazyllm.components.formatter import encode_query_with_filepaths>>> vlm = lazyllm.OnlineChatModule(source="sensenova", model="SenseChat-Vision")>>> query = "what is it?">>> inputs = encode_query_with_filepaths(query, ["/path/to/your/image"])>>> print(vlm(inputs))"""MODELS = {'openai': OpenAIModule,'sensenova': SenseNovaModule,'glm': GLMModule,'kimi': KimiModule,'qwen': QwenModule,'doubao': DoubaoModule,'deepseek': DeepSeekModule}@staticmethoddef _encapsulate_parameters(base_url: str, model: str, stream: bool, return_trace: bool, **kwargs) -> Dict[str, Any]:params = {"stream": stream, "return_trace": return_trace}if base_url is not None:params['base_url'] = base_urlif model is not None:params['model'] = modelparams.update(kwargs)return paramsdef __new__(self, model: str = None, source: str = None, base_url: str = None, stream: bool = True,return_trace: bool = False, skip_auth: bool = False, type: Optional[str] = None, **kwargs):if model in OnlineChatModule.MODELS.keys() and source is None: source, model = model, sourceparams = OnlineChatModule._encapsulate_parameters(base_url, model, stream, return_trace,skip_auth=skip_auth, type=type, **kwargs)if skip_auth:source = source or "openai"if not base_url:raise KeyError("base_url must be set for local serving.")if source is None:if "api_key" in kwargs and kwargs["api_key"]:raise ValueError("No source is given but an api_key is provided.")for source in OnlineChatModule.MODELS.keys():if lazyllm.config[f'{source}_api_key']: breakelse:raise KeyError(f"No api_key is configured for any of the models {OnlineChatModule.MODELS.keys()}.")assert source in OnlineChatModule.MODELS.keys(), f"Unsupported source: {source}"return OnlineChatModule.MODELS[source](**params)
class QwenModule(OnlineChatModuleBase, FileHandlerBase):"""#TODO: The Qianwen model has been finetuned and deployed successfully,but it is not compatible with the OpenAI interface and can onlybe accessed through the Dashscope SDK."""TRAINABLE_MODEL_LIST = ["qwen-turbo", "qwen-7b-chat", "qwen-72b-chat"]MODEL_NAME = "qwen-plus"def __init__(self, base_url: str = "https://dashscope.aliyuncs.com/", model: str = None,api_key: str = None, stream: bool = True, return_trace: bool = False, **kwargs):OnlineChatModuleBase.__init__(self, model_series="QWEN", api_key=api_key or lazyllm.config['qwen_api_key'],model_name=model or lazyllm.config['qwen_model_name'] or QwenModule.MODEL_NAME,base_url=base_url, stream=stream, return_trace=return_trace, **kwargs)FileHandlerBase.__init__(self)self._deploy_paramters = dict()if stream:self._model_optional_params['incremental_output'] = Trueself.default_train_data = {"model": "qwen-turbo","training_file_ids": None,"validation_file_ids": None,"training_type": "efficient_sft",  # sft or efficient_sft"hyper_parameters": {"n_epochs": 1,"batch_size": 16,"learning_rate": "1.6e-5","split": 0.9,"warmup_ratio": 0.0,"eval_steps": 1,"lr_scheduler_type": "linear","max_length": 2048,"lora_rank": 8,"lora_alpha": 32,"lora_dropout": 0.1,}}self.fine_tuning_job_id = Nonedef _set_chat_url(self):self._url = urljoin(self._base_url, 'compatible-mode/v1/chat/completions')

创建OnlineChatModule对象时设置参数source=qwen,返回QwenModule。

QwenModule可设置参数api_key,即除了像参考文档设置环境变量,还可以将key直接写在代码里。

base_url在代码执行时会进行修改,测试代码中的base_url可以走通……就没细研究……

执行对话

while True:query = input("query(enter 'quit' to exit): ")if query == "quit":breakres = llm.forward(query)print(f"answer: {res}") 

测试代码

from lazyllm import (OnlineChatModule,OnlineEmbeddingModule,Retriever,Document
)base_url_http = "https://dashscope.aliyuncs.com/compatible-mode"
llm=OnlineChatModule(source='qwen', model="qwen-plus", stream=False)while True:query = input("query(enter 'quit' to exit): ")if query == "quit":breakres = llm.forward(query)print(f"answer: {res}") 

执行结果

设置文档

文档使用方式时字符串转向量,通过向量运算获取结果。

doc_path="F:\\file\\my\\workplace\\agentLazyLLM\\lazyllm-venv\\docs"
embed_model = OnlineEmbeddingModule(source='qwen', embed_model_name='text-embedding-v4',type="embed")
doc = Document(dataset_path=doc_path, embed=embed_model)
retriever = Retriever(doc, group_name='CoarseChunk', similarity="bm25_chinese", topk=3)

OnlineEmbeddingModule为线上模型,用于字符串转向量。

该模型可用户文档搜索和重排,用变量type控制。

根据文档

class __EmbedModuleMeta(type):def __instancecheck__(self, __instance: Any) -> bool:if isinstance(__instance, OnlineEmbeddingModuleBase):return Truereturn super().__instancecheck__(__instance)class OnlineEmbeddingModule(metaclass=__EmbedModuleMeta):"""Used to manage and create online Embedding service modules currently on the market, currently supporting openai, sensenova, glm, qwen, doubao.Args:source (str): Specify the type of module to create. Options are  ``openai`` /  ``sensenova`` /  ``glm`` /  ``qwen`` / ``doubao``.embed_url (str): Specify the base link of the platform to be accessed. The default is the official link.embed_mode_name (str): Specify the model to access (Note that you need to use Model ID or Endpoint ID when using Doubao. For details on how to obtain it, see [Getting the Inference Access Point](https://www.volcengine.com/docs/82379/1099522). Before using the model, you must first activate the corresponding service on the Doubao platform.), default is ``text-embedding-ada-002(openai)`` / ``nova-embedding-stable(sensenova)`` / ``embedding-2(glm)`` / ``text-embedding-v1(qwen)`` / ``doubao-embedding-text-240715(doubao)``Examples:>>> import lazyllm>>> m = lazyllm.OnlineEmbeddingModule(source="sensenova")>>> emb = m("hello world")>>> print(f"emb: {emb}")emb: [0.0010528564, 0.0063285828, 0.0049476624, -0.012008667, ..., -0.009124756, 0.0032043457, -0.051696777]"""EMBED_MODELS = {'openai': OpenAIEmbedding,'sensenova': SenseNovaEmbedding,'glm': GLMEmbedding,'qwen': QwenEmbedding,'doubao': DoubaoEmbedding}RERANK_MODELS = {'qwen': QwenReranking,'glm': GLMReranking}@staticmethoddef _encapsulate_parameters(embed_url: str,embed_model_name: str,**kwargs) -> Dict[str, Any]:params = {}if embed_url is not None:params["embed_url"] = embed_urlif embed_model_name is not None:params["embed_model_name"] = embed_model_nameparams.update(kwargs)return params@staticmethoddef _check_available_source(available_models):for source in available_models.keys():if lazyllm.config[f'{source}_api_key']: breakelse:raise KeyError(f"No api_key is configured for any of the models {available_models.keys()}.")assert source in available_models.keys(), f"Unsupported source: {source}"return sourcedef __new__(self,source: str = None,embed_url: str = None,embed_model_name: str = None,**kwargs):params = OnlineEmbeddingModule._encapsulate_parameters(embed_url, embed_model_name, **kwargs)if source is None and "api_key" in kwargs and kwargs["api_key"]:raise ValueError("No source is given but an api_key is provided.")if "type" in params:params.pop("type")if kwargs.get("type", "embed") == "embed":if source is None:source = OnlineEmbeddingModule._check_available_source(OnlineEmbeddingModule.EMBED_MODELS)if source == "doubao":if embed_model_name.startswith("doubao-embedding-vision"):return DoubaoMultimodalEmbedding(**params)else:return DoubaoEmbedding(**params)return OnlineEmbeddingModule.EMBED_MODELS[source](**params)elif kwargs.get("type") == "rerank":if source is None:source = OnlineEmbeddingModule._check_available_source(OnlineEmbeddingModule.RERANK_MODELS)return OnlineEmbeddingModule.RERANK_MODELS[source](**params)else:raise ValueError("Unknown type of online embedding module.")

OnlineEmbeddingModule参数source='qwen'、type="embed",返回对象QwenEmbedding。

class QwenEmbedding(OnlineEmbeddingModuleBase):def __init__(self,embed_url: str = ("https://dashscope.aliyuncs.com/api/v1/services/""embeddings/text-embedding/text-embedding"),embed_model_name: str = "text-embedding-v1",api_key: str = None):super().__init__("QWEN", embed_url, api_key or lazyllm.config['qwen_api_key'], embed_model_name)

OnlineEmbeddingModule参数source='qwen'、type="rerank",返回重排对象QwenReranking。

class QwenReranking(OnlineEmbeddingModuleBase):def __init__(self,embed_url: str = ("https://dashscope.aliyuncs.com/api/v1/services/""rerank/text-rerank/text-rerank"),embed_model_name: str = "gte-rerank",api_key: str = None, **kwargs):super().__init__("QWEN", embed_url, api_key or lazyllm.config['qwen_api_key'], embed_model_name)

若embed_model_name未设置会报错,其值根据平台

Document设置本地文档,将本地文档和线上模型做关联,获取向量。

Retriever对向量进项解析。

测试代码

用户信息.txt

管理员  名字 王幺幺 性别 男
采购员  名字 王吾 性别 女
from lazyllm import (OnlineChatModule,OnlineEmbeddingModule,Retriever,Document
)
base_url_http = "https://dashscope.aliyuncs.com/compatible-mode"
doc_path="F:\\file\\my\\workplace\\agentLazyLLM\\lazyllm-venv\\docs"embed_model = OnlineEmbeddingModule(source='qwen', embed_model_name='text-embedding-v4',type="embed")
doc = Document(dataset_path=doc_path, embed=embed_model)
retriever = Retriever(doc, group_name='CoarseChunk', similarity="bm25_chinese", topk=3)
retriever_result = retriever(query="管理员性别")      context_str = "|".join([node.get_content() for node in retriever_result])
print("context_str:"+context_str)

执行结果

返回对应知识库信息,可通过线上对话模型返回对应信息。

设置工具

设置工具可将文档搜索和对象相管理。

用fc_register("tool")设置工具,文档必选设置。

@fc_register("tool")
def search_knowledge_base(query:str):"""搜索知识库并返回相关文档内容Args:query (str): 搜索查询字符串"""doc_node_list = retriever(query=query)context_str = "".join([node.get_content() for node in doc_node_list])return context_str

工具使用

agent = ReactAgent(llm,tools=['search_knowledge_base'],prompt=prompt,stream=False
)w  = WebModule(agent,stream=False)
w.start().wait()

llm是设置线上对话模型,工具调用线上向量模型和解析。

WebModule开启线上服务,参数设置ReactAgnet对像。

根据ReactAgne源码

lass ReactAgent(ModuleBase):"""ReactAgent follows the process of `Thought->Action->Observation->Thought...->Finish` step by step through LLM and tool calls to display the steps to solve user questions and the final answer to the user.Args:llm (ModuleBase): The LLM to be used can be either TrainableModule or OnlineChatModule.tools (List[str]): A list of tool names for LLM to use.max_retries (int): The maximum number of tool call iterations. The default value is 5.return_trace (bool): If True, return intermediate steps and tool calls.stream (bool): Whether to stream the planning and solving process.Examples:>>> import lazyllm>>> from lazyllm.tools import fc_register, ReactAgent>>> @fc_register("tool")>>> def multiply_tool(a: int, b: int) -> int:...     '''...     Multiply two integers and return the result integer......     Args:...         a (int): multiplier...         b (int): multiplier...     '''...     return a * b...>>> @fc_register("tool")>>> def add_tool(a: int, b: int):...     '''...     Add two integers and returns the result integer......     Args:...         a (int): addend...         b (int): addend...     '''...     return a + b...>>> tools = ["multiply_tool", "add_tool"]>>> llm = lazyllm.TrainableModule("internlm2-chat-20b").start()   # or llm = lazyllm.OnlineChatModule(source="sensenova")>>> agent = ReactAgent(llm, tools)>>> query = "What is 20+(2*4)? Calculate step by step.">>> res = agent(query)>>> print(res)'Answer: The result of 20+(2*4) is 28.'"""def __init__(self, llm, tools: List[str], max_retries: int = 5, return_trace: bool = False,prompt: str = None, stream: bool = False):super().__init__(return_trace=return_trace)self._max_retries = max_retriesassert llm and tools, "llm and tools cannot be empty."if not prompt:prompt = INSTRUCTION.replace("{TOKENIZED_PROMPT}", WITHOUT_TOKEN_PROMPT if isinstance(llm, OnlineChatModule)else WITH_TOKEN_PROMPT)prompt = prompt.replace("{tool_names}", json.dumps([t.__name__ if callable(t) else t for t in tools],ensure_ascii=False))self._agent = loop(FunctionCall(llm, tools, _prompt=prompt, return_trace=return_trace, stream=stream),stop_condition=lambda x: isinstance(x, str), count=self._max_retries)def forward(self, query: str, llm_chat_history: List[Dict[str, Any]] = None):ret = self._agent(query, llm_chat_history) if llm_chat_history is not None else self._agent(query)return ret if isinstance(ret, str) else (_ for _ in ()).throw(ValueError(f"After retrying \{self._max_retries} times, the function call agent still failes to call successfully."))

可以调用forward执行对话。

测试代码

base_url_http = "https://dashscope.aliyuncs.com/compatible-mode"
doc_path="F:\\file\\my\\workplace\\agentLazyLLM\\lazyllm-venv\\docs"
embed_model = OnlineEmbeddingModule(source='qwen', embed_model_name='text-embedding-v4',type="embed")
doc = Document(dataset_path=doc_path, embed=embed_model)
retriever = Retriever(doc, group_name='CoarseChunk', similarity="bm25_chinese", topk=3)
llm=OnlineChatModule(source='qwen', model="qwen-plus", stream=False,base_url=base_url_http)
# prompt 设计
prompt = '你是一个AI,说话风趣幽默,有耐心'
llm.prompt(ChatPrompter(instruction=prompt, extra_keys=['context_str']))@fc_register("tool")
def search_knowledge_base(query:str):"""搜索知识库并返回相关文档内容Args:query (str): 搜索查询字符串"""print(query)doc_node_list = retriever(query=query)context_str = "".join([node.get_content() for node in doc_node_list])return context_stragent = ReactAgent(llm,tools=['search_knowledge_base'],prompt=prompt,stream=False
)
res = agent.forward("管理员性别")
print(f"answer: {res}") 

直接结果

代码

import lazyllm
from lazyllm import (fc_register, Document, Retriever, OnlineEmbeddingModule, OnlineChatModule, WebModule,ReactAgent,Reranker,SentenceSplitter,pipeline
)
base_url_http = "https://dashscope.aliyuncs.com/compatible-mode"
doc_path="F:\\file\\my\\workplace\\agentLazyLLM\\lazyllm-venv\\docs"embed_model = OnlineEmbeddingModule(source='qwen', embed_model_name='text-embedding-v4',type="embed")doc = Document(dataset_path=doc_path, embed=embed_model)
retriever = Retriever(doc, group_name='CoarseChunk', similarity="bm25_chinese", topk=3)@fc_register("tool")
def search_knowledge_base(query:str):"""搜索知识库并返回相关文档内容Args:query (str): 搜索查询字符串"""doc_node_list = retriever(query=query)context_str = "".join([node.get_content() for node in doc_node_list])return context_strllm=OnlineChatModule(source='qwen', model="qwen-plus", stream=False,base_url=base_url_http)
# prompt 设计
prompt = '你是一个AI,说话风趣幽默,有耐心'
llm.prompt(lazyllm.ChatPrompter(instruction=prompt, extra_keys=['context_str']))agent = ReactAgent(llm,tools=['search_knowledge_base'],prompt=prompt,stream=False
)w  = WebModule(agent,stream=False)
w.start().wait()

执行结果

http://www.dtcms.com/a/415324.html

相关文章:

  • 服饰 公司 网站建设新会网页制作公司
  • 做网站开发的营业执照电商货源网站大全
  • Redis 主从同步:原理、配置与实战优化
  • 什么是网站反链企业建设网站风险
  • 毕业设计开题报告网站开发深圳哪家网站设计比较好
  • 常用的Python项目管理工具
  • 网站建设设计技术方案模板linux 下启动 wordpress
  • 温建设文件发布在哪个网站做网站需要ui设计吗
  • 数字孪生背后的通信协议:MQTT、OPC UA选型指南
  • Nest 身份鉴权与权限控制
  • C#系统日志
  • CMakeLists.txt语法(三)
  • 简单flash个人网站山东省建设教育集团网站首页
  • windows多显示器,独立的虚拟桌面
  • 国外的app设计网站企管宝官网
  • 深入解析 Redis 的两种持久化机制:RDB 与 AOF
  • 爱佳倍 北京网站软件外包公司是什么意思
  • SCNet平台—让AI更简单、更高效、更实用
  • 高流量网站设计菏泽网站开发公司
  • 做一个展示型网站要多少钱自己做本市网站
  • SSRF靶场环境命令执行靶场环境
  • 【数字孪生】02-数字孪生在各个领域的应用(1)
  • 网站字体样式重庆唐卡装饰口碑怎么样
  • wgcna 相关性热图中4个颜色 4个共表达模块 的模块基因是否都要做GO/KEGG分析”,核心取决于你的**研究目标和模块的生物学意义*
  • 什么是网站名称文件夹会展设计需要学什么
  • 第十六届蓝桥杯软件赛C组省赛C++题解(京津冀)
  • Spring Cloud 服务网关 Gateway 详解:微服务的 “统一入口” 实战
  • 基于 PyTorch 的模型测试与全局平均池化实践
  • 买软件网站建设福田祥菱v1单排
  • 江阴网站设计哪家好百度云用流量做网站