这是大模型实战营-初夏营第三次课 的笔记
前言
早就听闻茴香豆 ——“豆哥”的鼎鼎大名,现在借着初夏营这个机会体验一把,所以先把这个作业做了
环境配置
conda 虚拟环境配置
与第一期实战营不同,本期实战营在Intern
Studio上提供了非常方便的环境配置命令,仅需运行
1 studio-conda -o internlm-base -t InternLM2_Huixiangdou
即可一键配置运行豆哥所需的环境
在此基础之上,我们还需要安装一些python包:
1 2 3 4 5 6 7 8 pip install protobuf==4.25.3 accelerate==0.28.0 aiohttp==3.9.3 auto-gptq==0.7.1 bcembedding==0.1.3 beautifulsoup4==4.8.2 einops==0.7.0 faiss-gpu==1.7.2 langchain==0.1.14 loguru==0.7.2 lxml_html_clean==0.1.0 openai==1.16.1 openpyxl==3.1.2 pandas==2.2.1 pydantic==2.6.4 pymupdf==1.24.1 python-docx==1.1.0 pytoml==0.1.21 readability-lxml==0.8.1 redis==5.0.3 requests==2.31.0 scikit-learn==1.4.1.post1 sentence_transformers==2.2.2 textract==1.6.5 tiktoken==0.6.0 transformers==4.39.3 transformers_stream_generator==0.0.5 unstructured==0.11.2
激活环境之后可以运行下面的命令清理配置环境过程中的缓存:
1 2 pip cache purge conda clean -y --all
其中第二条命令清理出了12GB还多的空闲空间(也有可能是之前的东西太多没清理哈哈):
下载所需模型和仓库
bce-embedding,bce-reranker和InternLM-2模型
Intern Studio上已经准备好了上述模型的权重,只需建立软链接即可
1 2 3 4 5 6 cd /root && mkdir modelln -s /root/share/new_models/maidalun1020/bce-embedding-base_v1 /root/model/bce-embedding-base_ln -s /root/share/new_models/maidalun1020/bce-reranker-base_v1/ /root/model/bce-reranker-base_v1ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-7b /root/model/internlm2-chat-7b
1 2 3 4 cd /rootgit clone https://github.com/internlm/huixiangdou && cd huixiangdou git checkout ded0551
修改模型路径
我们还需要修改HuiXiangDou/config.ini
中的模型路径,文档是利用sed
命令直接在命令行修改的,这些命令的详细解释可以参考九月大佬的笔记 。还可以直接用VScode
SSH连接远程主机,直接在GUI上修改成下面这样也行:
1 2 3 4 5 6 7 8 embedding_model_path = "/root/model/bce-embedding-base_v1" reranker_model_path = "/root/model/bce-reranker-base_v1" ... local_llm_path = "/root/model/internlm2-chat-7b"
构建语料库
我们的目标是用豆哥做一个基于豆哥文档的RAG助手,主要用于解答用户关于豆哥的问题。首先需要从github上再次下载豆哥的源码作为语料:
1 2 3 cd /root/huixiangdou && mkdir repodirgit clone https://github.com/internlm/huixiangdou --depth=1 repodir/huixiangdou
除了语料知识的向量数据库,茴香豆建立接受和拒答两个向量数据库,用来在检索的过程中更加精确的判断提问的相关性,我们需要建立这两个语料库:
接受问题语料,即希望茴香豆助手回答的示例问题
存储在 HuiXiangDou/resource/good_questions.json
中,我们需要将原有的文件备份起来,生成一份新的语料,新语料和豆哥文档相关性更强
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 cd /root/huixiangdoumv resource/good_questions.json resource/good_questions_bk.jsonecho '[ "mmpose中怎么调用mmyolo接口", "mmpose实现姿态估计后怎么实现行为识别", "mmpose执行提取关键点命令不是分为两步吗,一步是目标检测,另一步是关键点提取,我现在目标检测这部分的代码是demo/topdown_demo_with_mmdet.py demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth 现在我想把这个mmdet的checkpoints换位yolo的,那么应该怎么操作", "在mmdetection中,如何同时加载两个数据集,两个dataloader", "如何将mmdetection2.28.2的retinanet配置文件改为单尺度的呢?", "1.MMPose_Tutorial.ipynb、inferencer_demo.py、image_demo.py、bottomup_demo.py、body3d_pose_lifter_demo.py这几个文件和topdown_demo_with_mmdet.py的区别是什么,\n2.我如果要使用mmdet是不是就只能使用topdown_demo_with_mmdet.py文件,", "mmpose 测试 map 一直是 0 怎么办?", "如何使用mmpose检测人体关键点?", "我使用的数据集是labelme标注的,我想知道mmpose的数据集都是什么样式的,全都是单目标的数据集标注,还是里边也有多目标然后进行标注", "如何生成openmmpose的c++推理脚本", "mmpose", "mmpose的目标检测阶段调用的模型,一定要是demo文件夹下的文件吗,有没有其他路径下的文件", "mmpose可以实现行为识别吗,如果要实现的话应该怎么做", "我在mmyolo的v0.6.0 (15/8/2023)更新日志里看到了他新增了支持基于 MMPose 的 YOLOX-Pose,我现在是不是只需要在mmpose/project/yolox-Pose内做出一些设置就可以,换掉demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py 改用mmyolo来进行目标检测了", "mac m1从源码安装的mmpose是x86_64的", "想请教一下mmpose有没有提供可以读取外接摄像头,做3d姿态并达到实时的项目呀?", "huixiangdou 是什么?", "使用科研仪器需要注意什么?", "huixiangdou 是什么?", "茴香豆 是什么?", "茴香豆 能部署到微信吗?", "茴香豆 怎么应用到飞书", "茴香豆 能部署到微信群吗?", "茴香豆 怎么应用到飞书群", "huixiangdou 能部署到微信吗?", "huixiangdou 怎么应用到飞书", "huixiangdou 能部署到微信群吗?", "huixiangdou 怎么应用到飞书群", "huixiangdou", "茴香豆", "茴香豆 有哪些应用场景", "huixiangdou 有什么用", "huixiangdou 的优势有哪些?", "茴香豆 已经应用的场景", "huixiangdou 已经应用的场景", "huixiangdou 怎么安装", "茴香豆 怎么安装", "茴香豆 最新版本是什么", "茴香豆 支持哪些大模型", "茴香豆 支持哪些通讯软件", "config.ini 文件怎么配置", "remote_llm_model 可以填哪些模型?" ]' > /root/huixiangdou/resource/good_questions.json
拒绝问题语料,即希望茴香豆助手拒答的示例问题
存储在HuiXiangDou/resource/bad_questions.json
中,
其中多为技术无关的主题或闲聊。我们无需改动这些语料
测试问题
存储在HuiXiangDou/test_queries.json
中,用于测试拒答效果
1 2 3 4 5 6 cd /root/huixiangdouecho '[ "huixiangdou 是什么?", "你好,介绍下自己" ]' > ./test_queries.json
运行以下命令建立向量数据库并使用测试问题测试
1 python3 -m huixiangdou.service.feature_store --sample ./test_queries.json
从命令行输出可以看到,豆哥接受第一个问题并且给出了最可能包含答案的文档README.md
而且豆哥拒绝回答第二个问题:
运行豆哥
修改一下main.py
中的测试query:
1 sed -i '74s/.*/ queries = ["huixiangdou 是什么?", "茴香豆怎么部署到微信群", "今天天气怎么样?"]/' /root/huixiangdou/huixiangdou/main.py
然后直接运行
1 python3 -m huixiangdou.main --standalone
效果如下
可以看到,豆哥的回答过程主要包括三个部分
问题打分:基于一定规则利用大模型给用户的问题打分(0~10分)低于一定阈值会直接拒答;看了一下技术报告和源码,大模型打分之前 还会通过用户问题与示例问题进行余弦相似度计算进行一次打分,如果所有示例问题打分均低于配置文件中的reject_throttle
,
则直接拒答;
问题主题提取:利用大模型提取问题主题,与技术不相关的主题(如天气)会被拒答;
检索并回答,就是RAG的通用pipeline了
gradio网页demo搭建
首先安装gradio
依赖:
1 pip install gradio==4.25.0 redis==5.0.3 flask==3.0.2 lark_oapi==1.2.4
gradio
, 启动!
1 2 cd /root/HuiXiangDoupython3 -m tests.test_query_gradio
可以使用VSCode终端的Port
页面直接将远端7860
端口映射到本地,之后直接访问http://127.0.0.1:7860 即可进入页面
提问:茴香豆怎么部署到微信群?
回答:
进阶实践1:开启搜索引擎
首先按照文档注册Serper并将API
key复制到config.ini
的web_search.x_api_key
下
按照上一个部分的步骤搭建一个网页demo
询问一个和豆哥无关,但与good_questions.json
中的示例问题相近的技术问题,结果没有回答:
翻源码看了一下code=3
是UNRELATED
说明提问与知识库无关,这个结果比较意外,虽然与知识库无关,但开启搜索引擎就应该有一个fallback去调用搜索引擎API,看了一下相关源码:
1 2 3 4 5 6 7 8 chunk, db_context, references = self.retriever.query( topic, context_max_length=self.context_max_length - 2 * len (self.GENERATE_TEMPLATE)) if db_context is None : tracker.log('feature store reject' ) return ErrorCode.UNRELATED, response, references
而网络搜索是在这之后执行的,所以这里的代码逻辑可能有问题。突然想起来这个分支不是main
于是我切换到main
分支再试试相同的操作,结果仍是如此(看了源码,虽然代码重构成了pipeline,但是内部逻辑没变),
提个issue 讨论一下这样设计的原因。
今天看到了maintainer大佬的回答,原来是我漏看了一部分代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 for node in pipeline: node.process(sess) if sess.code in exit_states: break if sess.code == ErrorCode.SUCCESS: check.process(sess) if sess.code == ErrorCode.SUCCESS: break
只有在检索到相关文档且回答错误 时才会进行下面的网络搜索和增强搜索等操作,至于为啥不在问题不相关时进行网络搜索,大佬的解释如下:
本地检索阈值卡得很低(topk 取 100, rerank 阈值也很低),
如果检索不到,大概率是个无关的话题。
无关的话题不应该再处理了。
检索低阈值给 UNRELATED 是表示拒答,
和 is_reject
有一点差异,在 chunk 切分上。
进阶实践2:使用远程模型
前两天刚好弄了个deepseek账号,有500万免费token,就先用deepseek试一下。
Hybrid方式,即local
和remote
都启用,
本地模型用于给问题打分,远程模型用于生成回答:
不过在这个分支上似乎不能正确请求deepseek的API
在main分支上试了一下Hybrid效果:
打分过程并没有调用deepseek API
非Hybrid方式(打分和回答都交给远程模型)在目前分支上会出现如下错误(现已修复:PR ):
再提个issue 问问吧
看issue中大佬的建议,我切回main分支试了一下,是可以正常运行的:
可以看到成功请求了deepseek API