前言
大家好,因为对AI大模型很感兴趣,相信很多兄弟们跟我一样,所以最近花时间了解了一些,有一些总结,分享给大家,希望对各位有所帮助。
本文将讲解如何在本地搭建一个简易的AI问答系统,主要用java来实现,也有一些简单的python知识;网上很多例子都是以 ChatGPT来讲解的,但因为它对国内访问有限制,OpeAi连接太麻烦,又要虚拟账号注册账号啥的,第一步就劝退了,所以选择了 llama和qwen替代,但是原理都是一样的。
前言
大家好,因为对AI大模型很感兴趣,相信很多兄弟们跟我一样,所以最近花时间了解了一些,有一些总结,分享给大家,希望对各位有所帮助。
相关概念了解
(一)大语言模型 LLM
1.定义:
◦大模型通常指的是拥有大量参数的深度学习模型,这些模型可能包含数十亿至数万亿的参数。
2.架构:
3.训练:
◦这些模型在大规模文本数据集上进行训练,这使得它们能够学习到语言的复杂结构,包括语法、语义、上下文关系等。
4.应用:
◦LLM可以应用于各种自然语言处理任务,包括但不限于文本生成、问答、翻译、摘要、对话系统等。
5.发展趋势:
◦学术研究和工业界都在探索LLM的边界,包括如何更有效地训练这些模型,以及如何使它们在不同领域和任务中更具适应性。
6.学习路径:
7.社区资源:
(二)Embedding
Embeddings 可以由预训练模型生成,也可以在特定任务中训练得到。常见的 embedding 方法包括:
1.Word2Vec:由 Google 提出,通过上下文预测目标词(CBOW)或通过目标词预测上下文(Skip-gram)来训练词向量。
2.GloVe:全球向量(Global Vectors for Word Representation),通过统计词共现矩阵来优化词向量。
3.FastText:Facebook 研究院提出的一种方法,它基于词 n-gram 来构建词向量,适用于稀少词和未见过的词。
4.BERT:基于 Transformer 架构的预训练模型,可以生成上下文相关的词嵌入,即“动态”词嵌入。
5.ELMo:利用双向 LSTM 语言模型生成的词嵌入,同样考虑了上下文信息。
(三)向量数据库
以下是向量数据库的一些关键特点和功能:
1.高维向量存储:向量数据库能够高效地存储和管理大量的高维向量数据,这些向量通常是由深度学习模型(如BERT、ResNet等)从原始数据中提取的特征。
2.相似性搜索:它们提供了快速的近似最近邻(Approximate Nearest Neighbor, ANN)搜索,能够在高维空间中找到与查询向量最相似的向量集合。
3.向量索引:使用特殊的数据结构,如树形结构(如KD树)、哈希表、图结构或量化方法,以加速向量的检索过程。
4.混合查询能力:许多向量数据库还支持结合向量查询和结构化数据查询,这意味着除了向量相似性搜索之外,还可以进行SQL风格的查询来筛选结构化属性。
5.扩展性和容错性:高效的数据分布和复制策略,使得向量数据库可以水平扩展,以处理海量数据,并且具备数据冗余和故障恢复能力。
6.实时更新:允许动态添加和删除向量数据,支持实时更新,这对于不断变化的数据集尤其重要。
(四)RAG
工作原理
1.检索(Retrieval):
当模型接收到一个输入或查询时,RAG 首先从外部知识库或数据源中检索相关信息。这通常涉及到使用向量数据库和近似最近邻搜索算法来找到与输入最相关的文档片段或知识条目。
一旦检索到相关的信息,这些信息会被整合到生成模型的输入中,作为上下文或提示(prompt)。这样,当模型生成输出时,它就能利用这些额外的信息来提供更准确、更详细和更相关的响应。
基本流程
RAG的优势:
1.减少知识局限性:LLMs 通常受限于其训练数据,而 RAG 可以让模型访问实时或最新的信息,从而克服这一限制。
2.减少幻觉:幻觉是指模型生成不存在于其训练数据中的不真实信息。RAG 通过提供事实依据,可以减少这种现象。
3.提高安全性:RAG 可以通过控制检索的范围和类型,避免模型生成潜在的有害或敏感信息。
RAG 可以应用于多种场景,包括但不限于:
问答系统:RAG 能够检索到与问题最相关的答案片段,然后基于这些片段生成最终的回答。
对话系统:在对话中,RAG 可以帮助模型引用历史对话或外部知识来生成更自然、更有信息量的回复。
文档摘要:RAG 能够从大量文档中提取关键信息,生成总结或概述。
文本补全:在文本补全任务中,RAG 可以参考相关文档来提供更准确的建议。
RAG 架构的一个重要组成部分是检索组件,它通常使用向量相似度搜索技术,如倒排索引或基于神经网络的嵌入空间搜索。这使得模型能够在大规模文档集合中快速找到最相关的部分。
AI应用开发框架
(一)Langchain
官网:https://www.langchain.com/langchain
LangChain不是一个大数据模型,而是一款可以用于开发类似AutoGPT的AI应用的开发工具,LangChain简化了LLM应用程序生命周期的各个阶段,且提供了 开发协议、开发范式,并 拥有相应的平台和生态;
LangChain 是一个由 Harrison Chase 创立的框架,专注于帮助开发者使用语言模型构建端到端的应用程序。它特别设计来简化与大型语言模型(LLMs)的集成,使得创建由这些模型支持的应用程序变得更加容易。LangChain 提供了一系列工具、组件和接口,可以用于构建聊天机器人、生成式问答系统、摘要工具以及其他基于语言的AI应用。
8.监控和调试工具:为了更好地理解和优化应用程序,LangChain 提供了日志记录和分析功能,帮助开发者追踪模型的行为和性能。
(二)LangChain4J
上面说的 LangChain 是基于python 开发的,而 LangChain4J 是一个旨在为 Java 开发者提供构建语言模型应用的框架。受到 Python 社区中 LangChain 库的启发,LangChain4J 致力于提供相似的功能,但针对 Java 生态系统进行了优化。它允许开发者轻松地构建、部署和维护基于大型语言模型的应用程序,如聊天机器人、文本生成器和其他自然语言处理(NLP)任务。
5.链式执行:通过链式执行,可以将多个语言处理步骤链接在一起,形成复杂的处理流程,例如先分析用户意图,再查询数据库,最后生成回复。
本地问答系统搭建环境准备
(一)用 Ollama 启动一个本地大模型
ollama 是一个命令行工具,用于方便地在本地运行 LLaMA 系列模型和其他类似的 transformer 基础的大型语言模型。该工具简化了模型的下载、配置和推理过程,使得个人用户能够在自己的机器上直接与这些模型交互,而不需要直接接触复杂的模型加载和推理代码;
下载地址:https://ollama.com/,下载完成后,打开 Ollma,其默认端口为11334,浏览器访问:http://localhost:11434 ,会返回:Ollama is running,电脑右上角展示图标;
安装完成后,通过命令行下载大模型,命令行格式:ollma pull modelName,如:ollma pull llama3;
大模型一般要几个G,需要等一会;个人建议至少下载两个, llama3、 qwen,这两个都是开源免费的,英文场景 用 llama3,中文场景用 qwen;
下载完成后,通过 ollma list 可以查看 已下载的大模型;
确认下载完成后,用命令行 :ollma run 模型名称,来启动大模型;启动后,可以立即输入内容与大模型进行对话,如下:
(二)启动 本地向量数据库 chromadb
1. 安装:pip install chromadb ;
2. 启动:chroma run :
用java实现 本地AI问答功能
(一)核心maven依赖:
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<langchain4j.version>0.31.0</langchain4j.version>
</properties>
<dependencies>
<!-- langchain4j -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-core</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-chroma</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- ollama -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-ollama</artifactId>
<version>${langchain4j.version}</version>
</dependency>
<!-- chroma 向量数据库 -->
<dependency>
<groupId>io.github.amikos-tech</groupId>
<artifactId>chromadb-java-client</artifactId>
<version>0.1.5</version>
</dependency>
</dependencies>
(二)代码编写:
1. 加载本地文件作为本地知识库:
public static void main(String[] args) throws ApiException {
//======================= 加载文件=======================
Document document = getDocument("笑话.txt");
}
private static Document getDocument(String fileName) {
URL docUrl = LangChainMainTest.class.getClassLoader().getResource(fileName);
if (docUrl == null) {
log.error("未获取到文件");
}
Document document = null;
try {
Path path = Paths.get(docUrl.toURI());
document = FileSystemDocumentLoader.loadDocument(path);
} catch (URISyntaxException e) {
log.error("加载文件发生异常", e);
}
return document;
}
//======================= 拆分文件内容=======================
//参数:分段大小(一个分段中最大包含多少个token)、重叠度(段与段之前重叠的token数)、分词器(将一段文本进行分词,得到token)
DocumentByLineSplitter lineSplitter = new DocumentByLineSplitter(200, 0, new OpenAiTokenizer());
List<TextSegment> segments = lineSplitter.split(document);
log.info("segment的数量是: {}", segments.size());
//查看分段后的信息
segments.forEach(segment -> log.info("========================segment: {}", segment.text()));
//提前定义两个静态变量
private static final String CHROMA_DB_DEFAULT_COLLECTION_NAME = "java-langChain-database-demo";
private static final String CHROMA_URL = "http://localhost:8000";
//======================= 文本向量化=======================
OllamaEmbeddingModel embeddingModel = OllamaEmbeddingModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3")
.build();
//======================= 向量库存储=======================
Client client = new Client(CHROMA_URL);
//创建向量数据库
EmbeddingStore<TextSegment> embeddingStore = ChromaEmbeddingStore.builder()
.baseUrl(CHROMA_URL)
.collectionName(CHROMA_DB_DEFAULT_COLLECTION_NAME)
.build();
segments.forEach(segment -> {
Embedding e = embeddingModel.embed(segment).content();
embeddingStore.add(e, segment);
});
//======================= 向量库检索=======================
String qryText = "北极熊";
Embedding queryEmbedding = embeddingModel.embed(qryText).content();
EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder().queryEmbedding(queryEmbedding).maxResults(1).build();
EmbeddingSearchResult<TextSegment> embeddedEmbeddingSearchResult = embeddingStore.search(embeddingSearchRequest);
List<EmbeddingMatch<TextSegment>> embeddingMatcheList = embeddedEmbeddingSearchResult.matches();
EmbeddingMatch<TextSegment> embeddingMatch = embeddingMatcheList.get(0);
TextSegment textSegment = embeddingMatch.embedded();
log.info("查询结果: {}", textSegment.text());
//======================= 与LLM交互=======================
PromptTemplate promptTemplate = PromptTemplate.from("基于如下信息用中文回答:\n" +
"{{context}}\n" +
"提问:\n" +
"{{question}}");
Map<String, Object> variables = new HashMap<>();
//以向量库检索到的结果作为LLM的信息输入
variables.put("context", textSegment.text());
variables.put("question", "北极熊干了什么");
Prompt prompt = promptTemplate.apply(variables);
//连接大模型
OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3")
.build();
UserMessage userMessage = prompt.toUserMessage();
Response<AiMessage> aiMessageResponse = ollamaChatModel.generate(userMessage);
AiMessage response = aiMessageResponse.content();
log.info("大模型回答: {}", response.text());
(三)功能测试
代码中用到 "笑话.txt" 是我随便从网上找的一段内容,大家可以随便输入点内容,为了给大家展示测试结果,我贴一下我 文本内容:
有一只北极熊和一只企鹅在一起耍,
企鹅把身上的毛一根一根地拔了下来,拔完之后,对北极熊说:“好冷哦!”
北极熊听了,也把自己身上的毛一根一根地拔了下来,
转头对企鹅说:
“果然很冷!”
当我输入问题:“北极熊干了什么”,程序打印如下结果:
结语
1.以上便是完成了一个超简易的AI问答功能,如果想搭一个问答系统,可以用Springboot搞一个Web应用,把上面的代码放到 业务逻辑中即可;
2.langchain 还有其他很多很强大的能力,prompt Fomat、output Fomat、工具调用、memory存储等;
参考资料:
1.langchain 官网(https://www.langchain.com/)
2.langchain 入门教程https://www.bilibili.com/video/BV1XC411n72m/)
3.langchain4j github(https://github.com/langchain4j/langchain4j)
4.langchain4j 视频介绍(https://www.bilibili.com/video/BV1mm421M7ag/)