引言
在现代自然语言处理领域中,语言模型(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---