LangChain 47 深入理解LangChain 表达式语言十一 Runnable 并行处理 LangChain Expression Language (LCEL)

LangChain系列文章

  1. LangChain 29 调试Debugging 详细信息verbose
  2. LangChain 30 ChatGPT LLM将字符串作为输入并返回字符串Chat Model将消息列表作为输入并返回消息
  3. LangChain 31 模块复用Prompt templates 提示词模板
  4. LangChain 32 输出解析器Output parsers
  5. LangChain 33: LangChain表达语言LangChain Expression Language (LCEL)
  6. LangChain 34: 一站式部署LLMs使用LangServe
  7. LangChain 35: 安全最佳实践深度防御Security
  8. LangChain 36 深入理解LangChain 表达式语言优势一 LangChain Expression Language (LCEL)
  9. LangChain 37 深入理解LangChain 表达式语言二 实现prompt+model+output parser LangChain Expression Language (LCEL)
  10. LangChain 38 深入理解LangChain 表达式语言三 实现RAG检索增强生成 LangChain Expression Language (LCEL)
  11. LangChain 39 深入理解LangChain 表达式语言四 为什么要用LCEL LangChain Expression Language (LCEL)
  12. LangChain 40 实战Langchain访问OpenAI ChatGPT API Account deactivated的另类方法,访问跳板机API
  13. LangChain 41 深入理解LangChain 表达式语言五 为什么要用LCEL调用大模型LLM LangChain Expression Language (LCEL)
  14. LangChain 42 深入理解LangChain 表达式语言六 Runtime调用不同大模型LLM LangChain Expression Language (LCEL)
  15. LangChain 43 深入理解LangChain 表达式语言七 日志和Fallbacks异常备选方案 LangChain Expression Language (LCEL)
  16. LangChain 44 深入理解LangChain 表达式语言八 Runnable接口输入输出模式 LangChain Expression Language (LCEL)
  17. LangChain 45 深入理解LangChain 表达式语言九 Runnable 调用、流输出、批量调用、异步处理 LangChain Expression Language (LCEL)
  18. LangChain 46 深入理解LangChain 表达式语言十 Runnable 调用中间状态调试日志 LangChain Expression Language (LCEL)

在这里插入图片描述

1. 并行性

让我们来看看LangChain表达语言如何支持并行请求。例如,当使用RunnableParallel(通常写成字典)时,它会并行执行每个元素。

1.1 先创建一个计算方法耗时的方法

在这个calc_time.py示例中,time.time() 返回当前时间的时间戳(以秒为单位)。通过在您的代码块执行前后分别记录时间,然后计算这两个时间戳的差值,您可以得到执行耗时。

如果您需要更精确地测量时间(例如,毫秒或微秒级别的精度),您可以使用 time.perf_counter(),它提供了更高分辨率的时钟:

import time

def measure_execution_time(func, *args, **kwargs):
    """测量并返回给定函数的执行时间。

    Args:
        func: 要测量的函数对象。
        *args: 传递给函数的位置参数。
        **kwargs: 传递给函数的关键字参数。

    Returns:
        tuple: (执行结果, 耗时秒数)
    """
    start_time = time.perf_counter()
    result = func(*args, **kwargs)
    end_time = time.perf_counter()
    elapsed_time = end_time - start_time
    return result, elapsed_time

# 示例:假设 chain1 已经定义并且具有 invoke 方法
# chain1 = ...

# 使用 measure_execution_time 来测量 chain1.invoke 的执行时间
# result, exec_time = measure_execution_time(chain1.invoke, {"topic": "bears"})
# print(f"执行结果: {result}")
# print(f"函数执行耗时: {exec_time} 秒")

1.2 单独执行和并行执行耗时对比

from langchain_core.runnables import RunnablePassthrough
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
import time
from calc_time import measure_execution_time
from dotenv import load_dotenv
load_dotenv()

from langchain_core.runnables import RunnableParallel

model = ChatOpenAI(model="gpt-3.5-turbo")
chain1 = ChatPromptTemplate.from_template("tell me a joke about {topic}") | model
chain2 = (
    ChatPromptTemplate.from_template("write a short (2 line) poem about {topic}")
    | model
)
combined = RunnableParallel(joke=chain1, poem=chain2)

# result, exec_time = measure_execution_time(chain1.invoke, {"topic": "bears"})
# print(f"执行结果: {result}")
# print(f"函数执行耗时: {exec_time} 秒")


# result, exec_time = measure_execution_time(chain2.invoke, {"topic": "bears"})
# print(f"执行结果: {result}")
# print(f"函数执行耗时: {exec_time} 秒")


result, exec_time = measure_execution_time(combined.invoke, {"topic": "bears"})
print(f"执行结果: {result}")
print(f"函数执行耗时: {exec_time} 秒")

单独执行的时间

⚡ python LCEL/parallelism.py
执行结果: content="Why don't bears like fast food?\n\nBecause they can't catch it!"
函数执行耗时: 2.450785037013702 秒
执行结果: content="Bears roam wild, majestic and free,\nNature's guardians, in mountains and trees."
函数执行耗时: 1.166965335025452

并行执行的耗时

⚡ python LCEL/parallelism.py                                                                                                           1 ↵
执行结果: {'joke': AIMessage(content="Sure, here's a bear joke for you:\n\nWhy don't bears ever wear shoes?\n\nBecause they have bear feet!"), 'poem': AIMessage(content="In forest's embrace,\nBears roam with gentle grace.")}
函数执行耗时: 2.161218732013367

1.3 批处理上的并行性

并行性可以与其他可运行项结合使用。让我们尝试在批处理中使用并行性。

# result, exec_time = measure_execution_time(chain1.batch, [{"topic": "bears"}, {"topic": "cats"}])
# print(f"执行结果: {result}")
# print(f"函数执行耗时: {exec_time} 秒")

# result, exec_time = measure_execution_time(chain2.batch, [{"topic": "bears"}, {"topic": "cats"}])
# print(f"执行结果: {result}")
# print(f"函数执行耗时: {exec_time} 秒")

result, exec_time = measure_execution_time(combined.batch, [{"topic": "bears"}, {"topic": "cats"}])
print(f"执行结果: {result}")
print(f"函数执行耗时: {exec_time} 秒")

单独执行的时间

⚡ python LCEL/parallelism.py
执行结果: [AIMessage(content="Why don't bears wear shoes?\n\nBecause they have bear feet!"), AIMessage(content="Why don't cats play poker in the wild?\n\nToo many cheetahs!")]
函数执行耗时: 3.1468410239904188 秒

zgpeace@zgpeaces-MacBook-Pro /Users/zgpeace/Workspace/LLM/langchain-llm-app                                                     develop
⚡ python LCEL/parallelism.py
执行结果: [AIMessage(content="In the forest's embrace,\nMajestic bears leave their trace."), AIMessage(content='Graceful feline souls, whiskers twitching in the night,\nPurring melodies, bringing comfort and delight.')]
函数执行耗时: 2.1072117580333725

批量处理的时间

CPU times: user 507 ms, sys: 125 ms, total: 632 ms
Wall time: 1.49 s

[{'joke': AIMessage(content="Why don't bears wear shoes?\n\nBecause they already have bear feet!"),
  'poem': AIMessage(content="Majestic bears roam,\nNature's wild guardians of home.")},
 {'joke': AIMessage(content="Sure, here's a cat joke for you:\n\nWhy did the cat sit on the computer?\n\nBecause it wanted to keep an eye on the mouse!"),
  'poem': AIMessage(content='Whiskers twitch, eyes gleam,\nGraceful creatures, feline dream.')}]

代码

https://github.com/zgpeace/pets-name-langchain/tree/develop

参考

https://python.langchain.com/docs/expression_language/why

langchain中,Runnable是一个接口,用于定义可以在单独线程中执行的任务。它是Java中多线程编程的基础之一。 要使用Runnable接口,你需要完成以下几个步骤: 1. 创建一个类并实现Runnable接口。这个类将包含你要在单独线程中执行的任务代码。你需要实现Runnable接口中的run()方法,该方法将在线程启动时被调用。 2. 在你的类中,可以添加其他成员变量和方法来支持你的任务。 3. 创建一个Thread对象,并将你实现了Runnable接口的类的实例作为参数传递给Thread的构造函数。 4. 调用Thread对象的start()方法,启动线程。这将导致run()方法被调用,并在单独线程中执行你的任务代码。 下面是一个简单的示例代码,展示了如何使用Runnable接口: ```java public class MyRunnable implements Runnable { public void run() { // 在这里编写你的任务代码 System.out.println("Hello, World!"); } } public class Main { public static void main(String[] args) { // 创建一个Runnable对象 MyRunnable myRunnable = new MyRunnable(); // 创建一个Thread对象,并将Runnable对象作为参数传递 Thread thread = new Thread(myRunnable); // 启动线程 thread.start(); } } ``` 以上代码中,我们创建了一个名为MyRunnable的类,它实现了Runnable接口,并在run()方法中打印了"Hello, World!"。然后,在主函数中,我们创建了一个Thread对象,并将MyRunnable的实例作为参数传递给Thread的构造函数。最后,我们调用Thread对象的start()方法,启动线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值