LangChain核心模块 Model I/O——LLMs

LLMs

Large Language Models (LLMs) 是LangChain的核心组件,LangChain不为自己的LLMs提供服务,而是提供一个标准接口来与许多不同的LLMs进行交互。具体来说,该接口是以字符串作为输入并返回字符串的接口。

关键问题:

  • 如何编写自定义LLM类 ——How to write a custom LLM class
  • 如何缓存LLM响应 ——How to cache LLM responses
  • 如何流式传输LLM的回复 ——How to stream responses from an LLM
  • 如何跟踪LLM通话中的令牌使用情况 —— How to track token usage in an LLM call

LLM接受字符串作为输入,或可以强制为字符串提示的对象,包括List[BaseMessage]PromptValue

Custom LLM

  • 自定义LLM

定制LLM只需要实现两件事:

  • 一个_call方法,它接受一个字符串、一些可选的停止词,并返回一个字符串。
  • 返回字符串的 _llm_type 属性,仅用于记录目的。

它可以实现第二个可选的东西:

  • _identifying_params 属性用于帮助打印此类。应该返回一个字典。

示例:实现一个简单的自定义 LLM,它只返回输入的前 n 个字符。

from typing import Any, List, Mapping, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM

class CustomLLM(LLM):
    n: int

    # 记录目的
    @property
    def _llm_type(self) -> str:
        return "custom"

    # 接受一个字符串、一些可选的停止词,并返回一个字符串。
    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        if stop is not None:
            raise ValueError("stop kwargs are not permitted.")
        return prompt[: self.n]

    # 用于帮助打印此类。应该返回一个字典。
    @property
    def _identifying_params(self) -> Mapping[str, Any]:
        """Get the identifying parameters."""
        return {"n": self.n}
llm = CustomLLM(n=10)
llm.invoke("This is a foobar thing")
'This is a '

还可以打印 LLM 并查看其自定义打印

print(llm)
CustomLLM
Params: {'n': 10}

Caching

LangChain 为 LLMs 提供了可选的缓存层。这样可以减少API的调用次数

from langchain.globals import set_llm_cache
from langchain_openai import OpenAI

# To make the caching really obvious, lets use a slower model.
llm = OpenAI(model_name="gpt-3.5-turbo-instruct", n=2, best_of=2)
%%time
from langchain.cache import InMemoryCache

set_llm_cache(InMemoryCache())

# The first time, it is not yet in cache, so it should take longer
llm.predict("Tell me a joke")
%%time
# The second time it is, so it goes faster
llm.predict("Tell me a joke")
SQLite Cache
!rm .langchain.db
# We can do the same thing with a SQLite cache
from langchain.cache import SQLiteCache

set_llm_cache(SQLiteCache(database_path=".langchain.db"))
%%time
# The first time, it is not yet in cache, so it should take longer
llm.predict("Tell me a joke")
%%time
# The second time it is, so it goes faster
llm.predict("Tell me a joke")

Streaming

​ 所有的LLMs都实现了Runnable接口,该接口有所有方法的实现,即ainvokebatchabatchstreamastream等,这为所有的LLMs提供了流媒体的支持。

​ 流媒体支持默认返回单个值的 Iterator(或异步流情况下的 AsyncIterator),即底层 LLM 提供程序返回的最终结果。这显然不会提供逐个令牌的流式传输,这需要 LLM 提供商的本机支持,但确保需要令牌迭代器的代码可以适用于我们的任何LLM集成。

在此处查看哪些集成支持逐个令牌流式传输

from langchain_openai import OpenAI

llm = OpenAI(model="gpt-3.5-turbo-instruct", temperature=0, max_tokens=512)
for chunk in llm.stream("Write me a song about sparkling water."):
    print(chunk, end="", flush=True)

Tracking token usage

  • 跟踪令牌使用情况

如何跟踪特定调用的令牌使用情况。目前仅针对 OpenAI API 实现。

下面是一个简单的示例,用于跟踪单个 LLM 调用的令牌使用情况

from langchain.callbacks import get_openai_callback
from langchain_openai import OpenAI

llm = OpenAI(model_name="gpt-3.5-turbo-instruct", n=2, best_of=2)
with get_openai_callback() as cb:
    result = llm.invoke("Tell me a joke")
    print(cb)

上下文管理器内的任何内容都会被跟踪。这是使用它按顺序跟踪多个回调的示例。

with get_openai_callback() as cb:
    result = llm.invoke("Tell me a joke")
    result2 = llm.invoke("Tell me a joke")
    print(cb.total_tokens)

如果使用包含多个步骤的链或代理,它将跟踪所有这些步骤。

from langchain.agents import AgentType, initialize_agent, load_tools
from langchain_openai import OpenAI

llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(
    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
with get_openai_callback() as cb:
    response = agent.run(
        "Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?"
    )
    print(f"Total Tokens: {cb.total_tokens}")
    print(f"Prompt Tokens: {cb.prompt_tokens}")
    print(f"Completion Tokens: {cb.completion_tokens}")
    print(f"Total Cost (USD): ${cb.total_cost}")

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值