文章目录
前言
了解了langchain-chatchat代码的必备知识之后,我们看代码轻松了许多,从这一期开始,我们正式开始看langchain-chatchat的代码。这一篇我们要讲的是langchain-chatchat是如何找到并实例化模型类的
一、疑惑的地方
一般我们都不会太去关注 ① 的代码,觉得只是取配置文件的信息,就直接往下走到 ②
进入②的函数,在如下的地方就会产生两个疑惑:
1)这个worker_class 到底是什么,是字符串吗?
2) 为什么它可以直接传值,变成一个 worker对象呢
二、回退之前的代码
1. 回退到run_model_worker
这个worker_class 只能是通过 下图 ① 产生的
2. 进入 get_model_worker_config
我们可以看到worker_class 是通过getattr(model_workers, provider) 产生的。
provider 之前的文章里介绍过,它来自配置文件 里的对应模型配置的 provider属性
那前面的 model_workers呢?
可以看到,它来自下面这句话
from server import model_workers
它是model_workers模块
3. getattr(model_workers, provider) 到底怎么运作的
我们可以写一段代码来测试下
if __name__ == "__main__":
import server.model_workers as model_workers
model = getattr(model_workers, "QwenWorker")
# 获取model的类名
print(model.__name__)
放到langchain-chatchat的根目录里,用debug模式运行它
第一步:可以看到 引入的model_workers模块实际上包含了它目录下面全部的类
第二步:可以看到通过 getattr 筛选了 QwenWorker这个类
4. 解析
1) 在model_workers模块下有一个 init.py 程序,它的代码是这样。
.base 里的 . 指的是 当前目录 也就是 当前目录里的 base.py 文件。以下以此类推。
那为什么其他的都是 明确类名,.base 引入的是 * 呢,因为base.py 里有多个类
通过import server.model_workers as model_workers
得到一个包含多个类的实例的模块。因为文件特别多,所以我们能感觉到代码有一段时间的延迟
from .base import *
from .zhipu import ChatGLMWorker
from .minimax import MiniMaxWorker
from .xinghuo import XingHuoWorker
from .qianfan import QianFanWorker
from .fangzhou import FangZhouWorker
from .qwen import QwenWorker
from .baichuan import BaiChuanWorker
from .azure import AzureWorker
from .tiangong import TianGongWorker
from .gemini import GeminiWorker
2)getattr(model_workers, “QwenWorker”) 获取 属性名为 QwenWorker的实例
总结
现在我们就能看懂这段代码了。我们看代码的时候可以更细节一些,遇到不明白的函数和流程最好不要囫囵吞枣的绕过去了。可以查查资料,弄明白。
对了还要补一小段。下面这种写法会在 pop之后,键"a"就被删掉了。langchain-chatchat特别喜欢用这个写法。所以如果还想往其他函数传kwargs ,我们就要特别注意是不是在上一个函数里被pop掉了
kwargs = {"a": 1, "b": 2}
print(kwargs.pop("a"))