尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

如何用 WB Tracer 追踪 LangChain 链的 Token 消耗、输入输出与耗时

如何用 WB Tracer 追踪 LangChain 链的 Token 消耗、输入输出与耗时 如何用 WB Tracer 追踪 LangChain 链的 Token 消耗、输入输出与耗时【免费下载链接】llm-cookbook面向开发者的 LLM 入门教程吴恩达大模型系列课程中文版项目地址: https://gitcode.com/GitHub_Trending/ll/llm-cookbook在调试 LLM 链或代理时一次运行背后会发生多步调用选参数、调工具、请求大模型。只看最终输出很难定位是哪一步耗时、哪一步多花了 token。本仓库的《选修-Evaluating and Debugging Generative AI》第五章 大语言模型评估以及用 WB 追踪 Evaluation and Tracing 演示了两种记录方式对自写的链用wandb.sdk.data_types.trace_tree里的Trace类显式打点对 LangChain 代理通过一个环境变量让 WB 自动记录。两种方式的记录内容都包括输入与输出、开始和结束时间、调用是否成功、token 使用量以及附加元数据。准备条件Python 环境。仓库的 环境配置 建议用 Anaconda 创建 Python 3.9 环境并安装openai等依赖本章代码还会用到wandb和tenacity重试装饰器。OpenAI API key按 环境配置 中的说明获取并按笔记本中的方式设置openai.api_key。登录 WB。笔记本中使用的是匿名登录方式不需要预先注册项目。导入并登录import os import random import time import datetime import openai from tenacity import ( retry, stop_after_attempt, wait_random_exponential, # 为指数回退 (for exponential backoff) ) import wandb from wandb.sdk.data_types.trace_tree import Trace # 获取 OpenAI 的 API openai.api_key sk-XXX # 替换为你自己的 key # 定义相应变量 PROJECT dlai_llm MODEL_NAME gpt-3.5-turbo # 登陆wandb wandb.login(anonymousallow)带退避重试的调用函数用于避免速率限制retry(waitwait_random_exponential(min1, max60), stopstop_after_attempt(6)) def completion_with_backoff(**kwargs): 这个函数能避免速率限制 (rate limits) return openai.ChatCompletion.create(**kwargs)用 Trace 显式追踪一条自定义链先看一条不经过 LangChain 的两步链WorldPicker随机选一个虚幻世界对应一个toolspan然后把结果拼进 Prompt 调 OpenAI 生成名字对应一个llmspan两个 span 都挂在顶层chainspan 下。文档说明中记录的字段正是标题关心的三类信息输入与输出、开始和结束时间、OpenAI 调用是否成功、token 使用量和额外元数据。worlds [ a mystic medieval island inhabited by intelligent and funny frogs, a modern castle sitting on top of a volcano in a faraway galaxy, a digital world inhabited by friendly machine learning engineers ] # 定义配置 model_name gpt-3.5-turbo temperature 0.7 system_message You are a creative copywriter. Youre given a category of game asset and a fantasy world. Your goal is to design a name of that asset. Provide the resulting name only, no additional description. Single name, max 3 words output, remember! def run_creative_chain(query): # 部分1 - 链开始了 start_time_ms round(datetime.datetime.now().timestamp() * 1000) # 顶层 root span root_span Trace( nameMyCreativeChain, kindchain, start_time_msstart_time_ms, metadata{user: student_1}, model_dict{_kind: CreativeChain} ) # 部分2 - 链随机选择一个虚幻世界 time.sleep(3) world random.choice(worlds) expanded_prompt fGame asset category: {query}; fantasy world description: {world} tool_end_time_ms round(datetime.datetime.now().timestamp() * 1000) # 创建一个tool span tool_span Trace( nameWorldPicker, kindtool, status_codesuccess, start_time_msstart_time_ms, end_time_mstool_end_time_ms, inputs{input: query}, outputs{result: expanded_prompt}, model_dict{_kind: tool, num_worlds: len(worlds)} ) # 将 tool span 添加为 root span 的子 root_span.add_child(tool_span) # 部分3 - 将工具 span 的输出传递至大语言模型 messages[ {role: system, content: system_message}, {role: user, content: expanded_prompt} ] response completion_with_backoff(modelmodel_name, messagesmessages, max_tokens12, temperaturetemperature) llm_end_time_ms round(datetime.datetime.now().timestamp() * 1000) response_text response[choices][0][message][content] token_usage response[usage].to_dict() llm_span Trace( nameOpenAI, kindllm, status_codesuccess, metadata{temperature: temperature, token_usage: token_usage, model_name: model_name}, start_time_mstool_end_time_ms, end_time_msllm_end_time_ms, inputs{system_prompt: system_message, query: expanded_prompt}, outputs{response: response_text}, model_dict{_kind: Openai, engine: response[model], model: response[object]} ) # 将大模型 span 添加为链 span 的子 root_span.add_child(llm_span) # 更新链 span 的输入和输出 root_span.add_inputs_and_outputs( inputs{query: query}, outputs{response: response_text}) # 更新链 span 的结束时间 root_span.end_time_ms llm_end_time_ms # 部分4 - 通过记录 root span 来记录所有 spans 到 WB root_span.log(namecreative_trace) print(fResult: {response_text})这段代码里几个打点约定值得注意每个 span 的start_time_ms/end_time_ms是毫秒时间戳耗时通过起止时间差体现。子 span 的开始时间接前一个 span 的结束时间llm_span的start_time_ms用的是tool_end_time_ms链的总结束时间由root_span.end_time_ms指定。token 消耗来自 API 响应的response[usage]含 prompt/completion/total tokens以token_usage放进llmspan 的metadata。inputs/outputs分别记录该步骤的输入 Prompt 与模型回答status_codesuccess表示这次调用成功。只有root_span.log(namecreative_trace)执行后整棵树才会上报只记录 root其所有子 span 会一并被记录。运行并开启一个新的 WB 记录# 开启新的 WB 表 wandb.init(projectPROJECT, job_typegeneration) # 运行 run_creative_chain(hero) run_creative_chain(jewel) wandb.finish()用环境变量自动追踪 LangChain 代理代理与固定链的区别在于每一步由大模型推理决定路径不确定因此更难调试——文档给出的理由正是使用追踪程序将会很有帮助。这一部分演示了让 WB 自动记录 LangChain 的方式只多一行环境变量# 导入需要的库 from langchain.agents import AgentType, initialize_agent from langchain.chat_models import ChatOpenAI from langchain.tools import BaseTool from typing import Optional from langchain.callbacks.manager import ( AsyncCallbackManagerForToolRun, CallbackManagerForToolRun, ) # 初始化 wandb.init(projectPROJECT, job_typegeneration) # 这将设置跟踪因此会自动记录这些跟踪 os.environ[LANGCHAIN_WANDB_TRACING] true文档明确说明LANGCHAIN_WANDB_TRACINGtrue的作用设置跟踪自动记录这些跟踪无需再对每个 span 手动打点。工具与代理的搭建工具各带一个time.sleep(1)用于模拟真实延迟便于在追踪里看到耗时class WorldPickerTool(BaseTool): name pick_world description pick a virtual game world for your character or item naming worlds [ a mystic medieval island inhabited by intelligent and funny frogs, a modern anthill featuring a cyber-ant queen and her cyber-ant-workers, a digital world inhabited by friendly machine learning engineers ] def _run( self, query: str, run_manager: Optional[CallbackManagerForToolRun] None ) - str: time.sleep(1) return random.choice(self.worlds) async def _arun( self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] None ) - str: raise NotImplementedError(pick_world does not support async) class NameValidatorTool(BaseTool): # 检查 query 或 name 是否少于20个字符 name validate_name description validate if the name is properly generated def _run( self, query: str, run_manager: Optional[CallbackManagerForToolRun] None ) - str: time.sleep(1) if len(query) 20: return fThis is a correct name: {query} else: return fThis name is too long. It should be shorter than 20 characters. async def _arun( self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] None ) - str: raise NotImplementedError(validate_name does not support async) # 实例化大模型 llm ChatOpenAI(temperature0.7, openai_api_keyopenai.api_key) # 生成可选择工具的list、生成代理 tools [WorldPickerTool(), NameValidatorTool()] agent initialize_agent( tools, llm, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, handle_parsing_errorsTrue, verboseTrue ) # 输入、运行 agent.run( Find a virtual game world for me and imagine the name of a hero in that world ) agent.run( Find a virtual game world for me and imagine the name of a jewel in that world ) wandb.finish()代理的每一步LLM 推理、工具调用都会由 WB 集成自动记录不再需要手写Trace。在 WB 中查看追踪结果文档给出的验证方式是回到 WB 网页自定义链打开运行结果行中的网址run_creative_chain打印结果之后对应的 WB 页面点击WorldPicker和OpenAI两个 span可以看到背后相应的过程——即每一步的输入、输出、起止时间与 token 使用量。LangChain 代理打开运行结果行中的网址点击相应板块同样可以查看背后的执行过程。注意文档中一条明确的说明大语言模型输出是可变的所以结果可能每次不一致。看追踪面板时应关注步骤结构、耗时与 token 数字的变化而不是期待复现某一次的具体文本。限制显式打点方式需要自己维护Trace对象、起止时间戳和add_child父子关系root_span.log()之前上报的内容不会进入记录LangChain 自动追踪依赖LANGCHAIN_WANDB_TRACING环境变量需要在agent.run之前设置两种路径都要求wandb.login成功后再wandb.init(projectPROJECT, job_typegeneration)开启记录结束时调用wandb.finish()。【免费下载链接】llm-cookbook面向开发者的 LLM 入门教程吴恩达大模型系列课程中文版项目地址: https://gitcode.com/GitHub_Trending/ll/llm-cookbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表