轻松实现自定义LLM类,让LangChain支持你的专属模型!

91 阅读2分钟

引言

在现代自然语言处理领域中,语言模型(LLM, Language Model)起到了至关重要的作用。然而,LangChain现有的封装可能无法满足所有开发者的需求。在本文中,我们将介绍如何创建一个自定义的LLM类,以便使用您自己的语言模型或不同于LangChain默认支持的封装器。通过遵循标准的LLM接口,您可以将自定义模型融入现有LangChain程序,并享受到异步支持和一些开箱即用的优化特性。

主要内容

创建自定义LLM的必需方法

实现一个自定义LLM类主要需实现以下两个方法:

  • _call: 接受一个字符串(以及一些可选的停止词),返回生成的字符串。
  • _llm_type: 这是一个用于日志记录的属性,返回模型类型的字符串。

可选实现

  • _identifying_params: 返回一个用于帮助识别模型及其输出的字典。
  • _acall: 异步版本的_call方法。
  • _stream: 实现模型输出的逐token流。
  • _astream: 异步版本的_stream方法。

实现示例

下面我们将实现一个简单的自定义LLM,该模型将返回输入中前n个字符。

from typing import Any, Dict, Iterator, List, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM
from langchain_core.outputs import GenerationChunk

class CustomLLM(LLM):
    """自定义聊天模型,返回输入的前 `n` 个字符。"""

    n: int

    def _call(self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> str:
        """运行LLM并返回结果。"""
        if stop is not None:
            raise ValueError("不支持提供停止词。")
        return prompt[: self.n]

    def _stream(self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> Iterator[GenerationChunk]:
        """逐字符地流式传输LLM的输出。"""
        for char in prompt[: self.n]:
            chunk = GenerationChunk(text=char)
            if run_manager:
                run_manager.on_llm_new_token(chunk.text, chunk=chunk)
            yield chunk

    @property
    def _identifying_params(self) -> Dict[str, Any]:
        return {"model_name": "CustomChatModel"}

    @property
    def _llm_type(self) -> str:
        return "custom"

代码示例

llm = CustomLLM(n=5)
print(llm.invoke("This is a foobar thing"))  # 输出: 'This '

常见问题和解决方案

停止词

自定义LLM在实现时,并不支持停止词逻辑,如果需要实现该功能,可以在_call方法中对生成的输出进行截断。

异步支持

我们的自定义模型中提供了异步流_astream,但在实现前请确保所有相关函数都是异步的。

总结和进一步学习资源

本文为您介绍了如何实现和测试一个简单的自定义LLM类。进一步学习,可以参考以下资源:

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---