[NLP/AIGC] 基于【大语言模型(LLM)】+【RAG】+【Fine-Tune(指令微调)】技术,构建智能体的方法 【待续】

news/2024/9/19 4:39:45/文章来源:https://www.cnblogs.com/johnnyzen/p/18411337

0 引言

引言

术语

  • AGI:通用人工智能AIGC:人工智能生成
  • LLM:大语言模型,ChatGPT、llama、千问、文心一言、KIMI都是大语言模型。langchain:一个对AI基础功能进行抽象的开发平台。作为一款先进的语言模型应用开发框架,可以让我们从基础、重复的代码中脱离。
  • RAG:检索增强生成。
  • Fine-Tunning:微调,让LLM学习我们整理好的知识,大多是专业细分领域的私有化数据集。

1 概述

关键技术:RAG/检索增强生成

定义与意义

  • Retrieval Augmented Generation/检索增强生成。

  • 它的主要作用生成(最终的答案),但是它先做了对现有文档的检索,而不是任由LLM(各大语言模型)来发挥

优化/解决LLM胡说八道的问题

  • 最通俗的解释:LLM都是自己的内容的时间限制,RAG则是添加一个私密的、专业的外挂知识集。

例如,ChatGPT 3.5,知识更新到2021年9月,在这之后的知识他并不了解。同时,一些非网络公开的知识(如企业自己的知识库)也是学习不到的。
为了解决这个问题,我们可以将企业的厚厚的《业务操作指南》交给LLM,让LLM去查询这本《业务操作指南》,并且认真阅读掌握业务方法。
当然,如果他碰到的业务知识比较复杂,他就需要自己去综合这本书上面的多个章节的内容,并融会贯通。
最后,用这本《业务操作指南》中的内容来回来我的问题。

简单来说:就是给LLM我们自己的知识内容,让LLM根据我们给出的知识去回答问题!

  • 那为什么不自己去看?
    有时候内容非常多,上百万字,自己去找十分困难。而LLM可以理解知识,并给出符合 我们要求的答案。

  • Fine-Tunning有什么不一样?

  • Fine-Tunning(微调)其实是在修改模型,给模型增加了新内容,但越是微调,专用性越强,通用性越弱。
  • 微调的内容其实是一问一答,即一个明确的问题确定的回答,避免回答的随机性
  • 即然是一问一答,直接检索就可以了,为什么还是fine-tunning?

因为LLM可以将相似的问题语义表述,认定为同一个问题用这一个答案来回答,这是检索不具备的。

  • 如:1、我今天吃了火锅有一些窜稀
  • 如:2、我今天吃了火锅有一些拉肚子

这在LLM里已经处理为相同的事情了,而如果检索就需要我们自己对输入的内容进行分析。简单说,fine-tunning帮我们将“相同的语义”但不同的“语言表达”归为相同的答案。
RAG相当于是给LLM加了一个外挂,即我们的知识库LLM本身并没有变化,只是在回答问题时,从知识库中摘取内容进行回答。

  • 怎么才能把我们的知识给LLM?

这就是RAG技术。具体的有如下的几个步骤:

  • 文档加载 → 文档分割 → 文档嵌入 → 向量化存储 → 文档检索 → 生成回答。

过程看着比较多,有个印象即可。每一步也有自己的优化点,这需要我们动手尝试,并不断的思考优化才能取得可用于生产的效果。

RAG的组成

  • 事实上,一个典型的 RAG 框架可以分为:
  • 检索器(Retriever)

检索过程包括:

  • 为数据(如 Documents)做切分
  • 嵌入向量(Embedding)
  • 并构建索引(Chunks Vectors)
  • 再通过向量检索,以召回相关结果
  • 生成器(Generator)
  • 生成过程,则是利用基于检索结果(Context)增强的 Prompt 来激活 LLM生成回答(Result)。

案例:用KIMI体验文档检索与知识抽取的便捷

  • 在我们正式开始RAG的编码之前,我们先来使用KIMI(https://kimi.moonshot.cn/)这个工具来体验一个用LLM进行检索的乐趣。

  • 进入KIMI,登陆一个账号,就可以开始进行对话了,但今天的重点是文件解析

例如,将一个PDF的招标书上传到KIMI

然后输入我的提示词:

你看,非常快捷的就把内容给精准的提炼了出来。你也可以快速的用手头的文档来练练手。这里要注意我们的提示词。

  • 提示词:LLM的角色 + 角色要求 + 我的目标 + 期望的输出 + 输出格式

具体到上述的问题:

“
kimi你好,这是我司的合同,你作为一个分析师,请你仔细的阅读文档内容。然后帮我分析一下我的下述几个属性:行业属性、产品属性、合同规模属性。行业属性,请你回答“行业:***”
只展示一个行业属性。产品属性请你回答“产品:**”,只展示一个产品属性。合同规模属性,请你回答“规模:**”。
”

我们进行一下拆解:

  • LLM的角色 : kimi你好,这是我司的合同,你作为一个分析师
  • 角色要求 : 请你仔细的阅读文档内容。
  • 期望的输出 : 然后帮我分析一下我的下述几个属性:行业属性、产品属性、合同规模属性。
  • 输出格式 : 行业属性,请你回答“行业:”,只展示一个行业属性。产品属性请你回答“产品:”,只展示一个产品属性。合同规模属性,请你回答“规模:*”。”

然后我们继续:

KIMI一样能给出不错的回答。LLM设计之初就更像一个文科生,对于文本的处理能力很强。
当然,处理数学问题比较差,毕竟这是理科问题
想象一下,当我们有大量的知识后,我们是希望像以前一些通过关键词检索,亦或是一篇篇的查找,还是希望这样快捷的、对话式的获得知识??

关键技术:Ollama(LLM私有部署与运行环境框架)

  • Ollama是大语言模型的运行环境,LLM并不是一个可执行文件,需要依托于一个运行环境才可以使用。

可百度搜索 Ollama 下载。

  • Ollama本身就200M+的大小,任何电脑都可以安装。

Ollama没有GUI,需要我们在CMD中运行。

关键技术:LangChain(LLM编程框架)

  • `LangChain·: 一个 LLM 编程框架、AI编程框架————其将基础的功能已经整合进来封装,减少我们的工作量。

langchain本身并不是LLM,需要我们安装好LLM,或使用在线api
你想开发一个基于 LLM 应用,需要什么组件它都有,直接使用就行;
甚至针对常规的应用流程,它利用链(LangChain中Chain的由来)这个概念已经内置标准化方案了。

  • LangChain的几大模块:
  • 提示模板
  • 示例选择器
  • 聊天模型
  • LLMs
  • 输出解析器
  • 文档加载器
  • 文本拆分器
  • 嵌入模型
  • 向量存储
  • 检索器
  • 索引
  • 工具
  • 代理
  • 多模态
  • 回调

看起来很多,但是你会发现,langchain已经将我们需要四处寻找的工具,都整合了进来,这样会节省我们大量的时间。

案例:基于 Lang Chain 完成一个最简单的代码任务

  • 为了实现这个目标,我们需要先进行如下的准备,然后才能开始进行代码的编写:
  • 1、使用ollama,在本地配置一个LLM;
  • 2、配置好PyCharm的环境;
  • 3、langchain等依赖库的安装。

Step1 安装本地部署与运行环境: Ollama

我们选择了自己部署,而自己私有化本地部署的一个工具就是Ollama,它可以在本地部署好我们的LLM,如llama`qwen等,Ollama`是这些LLM的运行环境。

完成安装后,输入ollama -v,能看到version就非常OK!

Step2 安装大语言模型/LLM : QWen2

但这只是一个空的运行环境,接下来要去安装一个LLM,这里我选择阿里的QWEN2

回到官网,点击页面右上角的"model",找到QWEN2。

点击进去后,这里可以在旁边看到安装的命令。

ollama run qwen2
  • 如果你的电脑性能一般,ollama的运行会比较慢。

Ollama对电脑的最低要求包括至少8GB的内存以流畅运行7B模型,‌而14B模型则需要至少16GB内存,‌72B模型则需要至少64GB内存。‌

  • 回到CMD中,输入上述命令。

看到开始安装。需要多长时间看自己的网速。

  • 完成后,回到CMD,输入ollama run qwen2,就可以运行大模型,并与其对话了。

有了这个模型后,我们可以安装一个webui,这样就可以像chatGPT一样在网页中对话。但我们今天的任务是使用代码进行对话,这样才能将整个过程结合到我们的业务中。

  • Ollama的接口服务器占用11434端口。所以,我们可以先在浏览器中查看此服务是否可用。

你自己也可以安装一些其它的模型来体验。

Step4 安装Python集成开发环境: PyCharm,并配置 LangChain

  • PyCharm我就不多说了,相信来学习Python、AI的都会使用,这里只给出我们需要在编码前,完成的一些依赖库安装。

如果你的pip版本老了,先升级一下。

python.exe -m pip install --upgrade pip

然后,执行下面的命令,安装langchain

pip install langchain
pip install langchain-community
pip install beautifulsoup4
  • 先放下langchain是什么的好奇心。现在,在我们完成Ollamallm,以后Python运行环境的准备后,我们输入这段代码:
def chat():prompt = ChatPromptTemplate.from_messages([("system", "{parser_instructions}"),("human", "列出{cityName}的{viewPointNum}个著名景点。")])model = Ollama(model="qwen2")output_parser = CommaSeparatedListOutputParser()parser_instructions = output_parser.get_format_instructions()# 查看解析器的指令内容print("----- 解析器 -----")print(parser_instructions)final_prompt = prompt.invoke({"cityName": "成都", "viewPointNum": 4, "parser_instructions": parser_instructions})response = model.invoke(final_prompt)print("----- response -----")print(response)ret = output_parser.invoke(response)print("------ret-----")print(ret);

运行后得到了结果:

运行时长依你的电脑配置而定,我的几秒,现在我们来解释一下代码。

  • 感受完了,小结一下————langchain最有价值的是组件

用于处理语言模型的抽象概念,以及每个抽象概念的实现集合。
无论你是否使用LangChain框架的其他部分,组件都是模块化的,易于使用。
现成的链:用于完成特定高级任务的组件的结构化组合。现成的链使人容易上手。
对于更复杂的应用和细微的用例,组件使得定制现有链或建立新链变得容易。
这些概念性的知识在实际运用前都是难以理解的,让我们直接开始看代码吧。

  • 从我们最直观的感受上来说,一个Chat的过程肯定是:

** 准备好提示词 -> 输入给LLM -> LLM => 反馈**

prompt = ChatPromptTemplate.from_messages([("system", "{parser_instructions}"),("human", "列出{cityName}的{viewPointNum}个著名景点。")])
### 这里是使用了langchain的提示词模板,system中的
### parser_instructions是对于输出的要求
### human中的cityName和viewPointNum是我们的问题中动态输入的参数。

然后下一段

model = Ollama(model="qwen2")
### 定义了我们要使用的LLM,这里我使用了“千问”output_parser = CommaSeparatedListOutputParser()
parser_instructions = output_parser.get_format_instructions()
### 这里定义了输出的解析方式 CommaSeparatedListOutputParser
### 除此之外,还有 DatetimeOutputParser、EnumOutputParser 等多种解析器

完成了提示词、大模型选择、输出定义后,但并没有运行起来。需要我们在后面的代码中,使用invoke

    final_prompt = prompt.invoke({"cityName": "成都", "viewPointNum": 4, "parser_instructions": parser_instructions})###对prompt使用invoke,将我们的输入绑定到提示词模板,形成final_prompt response = model.invoke(final_prompt)print("----- response -----")print(response)### 对model使用invoke,将final_prompt提交给LLM,也就是qwen2,### 最后得到一个response,这是一个message,需要解析成我们需要的格式。ret = output_parser.invoke(response)print("------ret-----")print(ret);### 将response提交给output_parser,得到分隔开的一个字段串数组类型的输出。
  • 怎么样!是不是十分的简单。在这段代理里使用了提示词模板、模型、输出解析器。但前面提到的最重要的链好像并没有用到。
  • langchain使用了LCEL表达语言,我们可以将上述的运行部分用这样的方式来替代,一样可以得到结果。
chain = prompt | llm | output_parse
rrrr = chain.invoke({"cityName": "成都", "viewPointNum": 4, "parser_instructions": parser_instructions})
  • 这就是langchain的链的表达,虽然这只是一个最简单的链,但我们已经初步的感受到,链就是一个工作流,将我们的工作串起来,避免了Invoke满天飞。
  • 在langchain中,实际上已经定义了很多的chain,当我们更加的熟悉后,我们可以使用现有的链。

X 参考文献

  • 【五天入门RAG】第一天:使用KIMI体验大模型的文本处理 - Weixin/AIGC中文站 2024.07.19
  • 【五天入门RAG】第二天:使用langchain完成一个最简单的代码任务 - Weixin/ 2024.07.20
  • 【LLM大模型】大模型之RAG,LLM性能的提升,RAG与Fine-Tune我们该如何选择? - CSDN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/796359.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读构建可扩展分布式系统:方法与实践02分布式系统架构简介

分布式系统架构简介1. 系统架构基础 1.1. 几乎所有大规模系统都是从小规模开始,在成功路上逐渐发展壮大 1.2. 通信使用标准的应用层网络协议,通常是HTTP 1.3. Java EE和Java的Spring框架 1.4. Python的Flask 1.5. 随着应用程序的特性变得更加丰富,单体应用程序的复杂性往往会…

ch07_oop_fundamentals

第7章 面向对象编程(基础部分)类与对象类和对象的区别和联系 对象在内存中存在形式! 属性/成员变量/字段 如何创建对象 如何访问属性成员方法方法的调用机制原理! 成员方法的好处 成员方法的定义成员方法传参机制引用数据类型的传参机制 成员方法返回类型是引用类型应用实例方法…

机器学习作业4

机器学习作业4 学号:102102156 姓名:高涛 1. 图像聚类 1.1 代码1.2 绘制结果2.图像特征脸(eigenfaces) 2.1 代码2.2 绘制结果![image-20240913014823493] 3.1 图像降维 3.1 代码3.2 绘制结果

软工个人项目-论文查重

软工个人项目-论文查重这个作业属于哪个课程 广工计院计科34班软工这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229这个作业的目标 个人独立完成论文查重代码,进一步了解项目开发的流程,学会运用工具分析消除警告,运用性能分析工具进行…

和PLC对配置的繁琐工序

上位机开发最烦和PLC对轴的位置,点的位置,一大堆的手写工序,数据不是放在Excel表,就是放在txt或者ini 图1.图2这次的需求 我需要手动将图1的数据写到图2 太麻烦 所以我准备写一个工具实现它 首先,我打算生成图2,需要使用到XML反序列化,读取图1,我使用MiniExcel 所以我先…

Redis入门 - C#|.NET Core封装Nuget包

分享封装Redis C#库并打包成Nuget包的方法,旨在增强代码可测试性、解耦及扩展Redis功能。通过封装Redis客户端库,提供统一接口,便于测试、替换和扩展功能,同时支持依赖注入,简化配置和使用。经过前面章节的学习,可以说大家已经算Redis开发入门了。已经可以去到项目上磨砺…

vue3项目部署到Github

此教程适应于以webpack,vue-cli,vite等脚手架构建的vue项目。当然,vue2和vue3都是可以滴。1. 前提:你的代码库已经提交到Github上 如果没有的话,请到GitHub上新建仓库,并把你本地的项目提交到GitHub上新建的仓库里。 具体方法,可以参考我的博客 Git使用记录 - 持续更新 …

[极客大挑战 2019]LoveSQL 1

启动靶机作者不建议使用sqlmap我们这里就进行手工注入 用万能口令登录 admin or 1 =1# ,详情见上文(https://www.cnblogs.com/m1saka1/p/18411197) 登录成功获得用户名和密码,发现密码并没有卵用,只能换思路利用账号密码的回显页面进行sql注入爆破数据库 由于网站自动转义,…

Go日志管理库zap

一、zap介绍 在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能: 1.能够将事件记录到文件中,而不是应用程序控制台。 2.日志切割-能够根据文件大小、时间或间隔等来切割日志文件。 3.支持不同的日志级别。例如INFO,DEBUG,ERROR等。 4.能够打印基本信息,…

深度神经网络DNN、RNN、RCNN及多种机器学习金融交易策略研究|附数据代码

全文链接:https://tecdat.cn/?p=37668 原文出处:拓端数据部落公众号 分析师:Aijun Zhang 在当今的金融领域,量化交易正凭借其科学性和高效性逐渐成为主流投资方式之一。随着大数据技术的蓬勃发展,量化交易借助先进的数学模型和计算机分析能力,摒弃了人的主观判断,通过…

第一次个人作业

这个作业属于哪个课程 班级的链接这个作业要求在哪里 作业要求的链接这个作业的目标 实现论文查重算法,并对代码进行性能分析、单元测试,使用PSP表GitHub链接 一、PSP表PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)Planning 计划 15 20Estimate 估…