当前位置: 首页 > news >正文

【Spring AI】基于SpringAI+Vue3+ElementPlus的QA系统实现一

整理不易,请不要吝啬你的赞和收藏。

1. 前言

这是 SpringAI 系列的第二篇文章,这篇文章将介绍如何基于 RAG 技术,使用 SpringAI + Vue3 + ElementPlus 实现一个 Q&A 系统。本文使用 deepseek 的 DeepSeek-V3 作为聊天模型,使用阿里百炼的 text-embedding-v3 作为向量模型,使用 redis 作为向量库。(PS:近期阿里百炼也上架了DeepSeek-V3  DeepSeek-R1 模型供开发者调用,如果觉得 DeepSeek 官方 AP I比较慢的话,可以去试试)。

什么是 RAG?

RAG(Retrieval-Augmented Generation,检索增强生成)技术是一种结合了检索(Retrieval)和生成(Generation)的自然语言处理方法。它通过检索相关的文档片段来增强语言模型的生成能力,从而提高生成文本的质量和相关性。RAG技术的核心思想是利用检索系统从大规模文档集合中找到与输入问题最相关的文档片段,然后将这些片段作为上下文信息输入到生成模型中,生成更加准确和详细的回答。

注:以下几行内容节选自 spring ai alibaba RAG 部分说明文档。

RAG 的工作流程分为两个阶段:Indexing pipeline 和 RAG 。

  • Indexing pipeline 阶段主要是将结构化或者非结构化的数据或文档进行加载和解析、chunk切分、文本向量化并保存到向量数据库。

  • RAG 阶段主要包括将 promp t文本内容转为向量、从向量数据库检索内容、对检索后的文档 chunk 进行重排和 prompt 重写、最后调用大模型进行结果的生成。

下面是大致流程:

2. 效果展示

让聊天模型基于我上传的文件,进行回答。

3. 设计思路

整个 Q&A 功能的时序图:

4. 前提条件

  • 已有自己的向量库,如 Redis、Faiss。想了解更多参考我的博客:

    【LLM】Redis 作为向量库入门指南_redis 向量数据库-CSDN博客文章浏览阅读1k次,点赞25次,收藏12次。这篇文章将介绍基于 RedisSearch 的Redis向量库实现。通过阅读本篇文章,你将学习到如何创建向量索引,如何存储和更新向量,如何进行向量搜索,如何使用阿里百炼 Embedding Model 文本向量化,如何集成到 spring boot 中并实现向量的存储和搜索等。_redis 向量数据库 https://blog.csdn.net/u013176571/article/details/145122380
  • 已安装 18.3 或更高版本的 Node.js ,未安装进入 官网下载 ,LTS 为长期支持版,Current 为最新功能版。

  • 使用过Spring AI,可参考我的这篇博客:

    【Spring AI】Spring AI Alibaba的简单使用_spring-ai-alibaba-starter-CSDN博客文章浏览阅读696次,点赞7次,收藏6次。项目中引入Spring AI、Spring AI Alibaba踩坑笔记,并实现简单的几种聊天模式。_spring-ai-alibaba-starter https://blog.csdn.net/u013176571/article/details/144488475

需要注意:写这篇文章的时候,我对 spring-ai-core 版本进行了升级,版本为:1.0.0-M5。并且舍弃了 spring-ai-alibaba-starter 包,改为引入使用更广泛的 spring-ai-openai 包,这些修改意味着之前写的文章中的部分代码要做相应的修改,下文将会介绍。

5. 引入 Spring AI

5.1 pom 文件配置

spring-ai 版本为 1.0.0-M5。

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-core</artifactId><version>${spring-ai-core.version}</version>
</dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai</artifactId><version>${spring-ai-core.version}</version>
</dependency>

由于 spring-ai 相关依赖包还没有发布到中央仓库,需要在项目的 pom.xml 依赖中加入如下仓库配置。

<repositories><repository><id>maven2</id><name>maven2</name><url>https://repo1.maven.org/maven2/</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories>

maven 的 setting.xml 中做出如下更改

<mirror>  <id>alimaven</id>  <name>aliyun maven</name>  <url>https://maven.aliyun.com/repository/public</url> <!-- 表示除了spring-milestones、maven2其它都走阿里云镜像  --> <mirrorOf>*,!spring-milestones,!maven2</mirrorOf>  
</mirror>

5.2 application.yml 配置

聊天模型基于 deepseek,‘your-api-key’ 为 deepseek 上申请的api-key,base-url 设置为 deepseek 的接口 url。

spring:ai:openai:api-key: your-api-keybase-url: https://api.deepseek.comchat:model: deepseek-chatchat:client:enabled: false

6. 接口开发

由于我们使用的是 spring-ai-openai 依赖,依赖中的 ChatModel 、 EmbeddingModel 等 Bean 默认配置都是基于 OpenAI 的模型,所以我们都需要根据自己使用的模型重新注册这些 Bean。

6.1 注册 EmbeddingModel

从上文的 RAG 流程中我们知道,实现 Q&A 系统的第一步是将知识库的资源向量化(也就是 Embedding)。

我这里使用阿里百炼的嵌入模型,下图是其主要文本向量模型对比:

这篇文章使用 text-embedding-v3,需要新注册一个 EmbeddingModel Bean。

@Bean
public EmbeddingModel embeddingModel() {return new OpenAiEmbeddingModel(// embeddingBaseUrl 为阿里百炼的接口 url ,值为:https://dashscope.aliyuncs.com/compatible-mode// embeddingApiKey 为阿里百炼上申请的 api-key 。new OpenAiApi(embeddingBaseUrl, embeddingApiKey),MetadataMode.EMBED,OpenAiEmbeddingOptions.builder().model("text-embedding-v3")  // 选用的嵌入模型.dimensions(1024)            // 向量维度.build(),RetryUtils.DEFAULT_RETRY_TEMPLATE);
}

6.2 注册 ChatModel

我使用 DeepSeek 的 DeepSeek-V3 作为聊天模型,这里需要重新注入 ChatModel Bean。

@Bean
public ChatModel chatModel() {// baseUrl 为 DeepSeek 接口 url,值为:https://api.deepseek.com// apiKey 为申请的秘钥,defaultChatModel 为聊天模型。return new OpenAiChatModel(new OpenAiApi(baseUrl, apiKey), OpenAiChatOptions.builder().model("deepseek-chat")    // 选用的聊天模型.temperature(0.7d)         // .build());
}

6.3 注册 VectorStore

我的这篇文章

【LLM】RedisSearch 向量相似性搜索在 SpringBoot 中的实现_jedis ftsearch-CSDN博客文章浏览阅读762次,点赞11次,收藏11次。这篇文章将介绍两种实现方式,第一种为使用Jedis中的UnifiedJedis类实现,第二种为使用SpringAI中的VectorStore实现。通过这边文章你将收获,如何使用阿里百炼Embedding模型实现文本向量化,如何通过连接池获取UnifiedJedis对象,如何在SpringBoot中实现向量数据的存储以及使用fTSearch进行向量相似性搜索,如何使用SpringAI的VecotStore。_jedis ftsearch https://blog.csdn.net/u013176571/article/details/145235761

做过详细介绍,这里增加两个元数据配置 docId(文档Id) 和 docName(文档名),用于在回答的时候进行过滤。

@Bean
public VectorStore vectorStore() {return RedisVectorStore.builder(jedisPooled, embeddingModel).indexName(indexName).prefix(prefix).embeddingFieldName("embedding")      // 向量字段名,默认 embedding.contentFieldName("content")          // 存储的原始文本内容.initializeSchema(initializeSchema)   // 是否初始化索引配置信息.batchingStrategy(batchingStrategy).metadataFields(RedisVectorStore.MetadataField.text(SpringAIConst.VectorStore.METADATA_DOC_ID),   // 存储的元数据信息RedisVectorStore.MetadataField.text(SpringAIConst.VectorStore.METADATA_DOC_NAME)  // 存储的元数据信息).build();
}

6.4 文档 Embedding

文本文档 Embedding 之前要先对文本文档进行分割,以满足大模型接口的输入字符数或者 Token 限制。

6.4.1 文档分割

文本分割的算法有:字符分割、递归字符文本分割、语义文档分割等等,如果有需要我将在后续文章中介绍这些算法。

本文使用较为常见的:递归字符文本分割。在递归字符文本分割中,通常会按照分隔符的优先级逐步分割文本。以英文常用的分隔符为例 ["\n\n", "\n", " "] ,其表示先用 "\n\n" 分割成段落,然后在每个段落中用 "\n" 分割成行,最后在每行中用 " " 分割成单词,这种逐层分割的方式可以将文本逐步细化为更小的单元。

public class RecursiveCharacterTextSplitter implements TextSplitterIntf {/*** 分隔符列表,用于拆分文本* 中文:"\n\n", "。", "!", "?", ",", ";"* 英文:"\n\n", "\n", " "*/private List<String> separators = Arrays.asList("\n\n", "。", "!", "?", ",", ";");/*** 每个块的最大大小*/private int chunkSize = 250;/*** 块之间的重叠大小,用来维持上下文关系*/private int chunkOverlap = 30;public RecursiveCharacterTextSplitter() {}public RecursiveCharacterTextSplitter(int chunkSize, int chunkOverlap) {this.chunkSize = chunkSize;this.chunkOverlap = chunkOverlap;if (chunkOverlap >= chunkSize) {throw new IllegalArgumentException("chunkOverlap must be smaller than chunkSize");}}public RecursiveCharacterTextSplitter(List<String> separators, int chunkSize, int chunkOverlap) {this.separators = separators;this.chunkSize = chunkSize;this.chunkOverlap = chunkOverlap;if (chunkOverlap >= chunkSize) {throw new IllegalArgumentException("chunkOverlap must be smaller than chunkSize");}}/*** Spring ai Document 拆分** @param documents* @param metaData  文档元数据信息* @return*/@Overridepublic List<Document> split(List<Document> documents, List<Map<String, Object>> metaData) {List<JSONObject> docList = this.beforeSplit(documents, metaData);List<Document> chunkedDocuments = new ArrayList<>();docList.forEach(item -> {Document document = item.getObject("document", Document.class);Map<String, Object> singleMetaData = item.getObject("metaData", Map.class);List<String> chunks = new ArrayList<>();splitRecursive(document.getContent(), chunks);chunks.forEach(chunk -> {chunkedDocuments.add(new Document(chunk, singleMetaData));});});return chunkedDocuments;}/*** 递归地拆分文本** @param text* @param chunks*/private void splitRecursive(String text, List<String> chunks) {if (text.length() <= chunkSize) {chunks.add(text);return;}String separator = findBestSeparator(text);if (separator == null) {chunks.add(text);return;}String[] parts = text.split(separator, -1);StringBuilder currentChunk = new StringBuilder();int currentLength = 0;for (String part : parts) {if (currentLength + part.length() > chunkSize) {if (currentChunk.length() > 0) {chunks.add(currentChunk.toString());// 通过回退chunkOverlap的距离创建来重叠部分int overlapStart = Math.max(0, currentChunk.length() - chunkOverlap);currentChunk = new StringBuilder(currentChunk.substring(overlapStart));currentLength = currentChunk.length();}}currentChunk.append(part).append(separator);currentLength += part.length() + separator.length();}if (currentChunk.length() > 0) {chunks.add(currentChunk.toString());}}/*** 查找文本中第一个出现的分隔符** @param text* @return*/private String findBestSeparator(String text) {for (String separator : separators) {if (text.contains(separator)) {return separator;}}return null;}
}

6.4.2 BatchingStrategy 介绍

每个 Embedding 模型都有最大处理 token 数限制,对于一个大文档,我们不能够一次性发送给模型处理,为了解决这个问题,Spring AI 实现了一种批处理策略,这个方法将大量文档分解成更小的批次,不仅能够适配 Embedding Model 的最大上下文,还能够提高性能并更有效地利用API速率限制。

Spring AI 通过 BatchingStrategy 接口提供此功能,该接口允许根据文档的 token 数量将文档处理为子批次,这个接口有一个默认实现 TokenCountBatchingStrategy ,这里我们需要根据自己选择的模型重新注册该 Bean。

@Bean
public BatchingStrategy tokenCountBatchingStrategy() {return new TokenCountBatchingStrategy(EncodingType.CL100K_BASE,  // 指定用于分词的编码类型8000,                      // 最大 Token 数量0.1                        // 设置预留百分比(默认 10%));
}

参数解释:

  • EncodingType.CL100K_BASE:指定用于分词的编码类型。这种编码类型被 JTokkitTokenCountEstimator 使用,以准确估计token数量。

  • 8000:最大 Token 数量,默认使用 OpenAI 的最大输入token数(8191)。

  • 0.1:设置预留百分比(默认 10%),从最大输入token数中预留的token百分比,这为处理过程中可能的token数量增加创建了一个缓冲区。

6.5 保存文档到向量库

6.5.1 分割后的文本入向量库

为了防止同一文档重复入库,在文档入库前先计算文档的 Hash 值,并在文档保存到向量库后,将文档的信息(文档名,文档大小,分割文本大小等)保存到 Redis 中(key 为文档 Hash 值),方便后续操作中的重复判断。

    /*** 文档入库** @param inputStream 文档输入流* @param docHash     文档Hash* @param docName     文档名* @throws Exception*/public void addDocument(InputStream inputStream, String docHash, String docName) throws Exception {// 校验文档是否已经存在if (redisService.hasKey(CommonConst.RAG_KEY_PREFIX + docHash)) {return;}int docSize = inputStream.available();// 文件流转为 DocumentTextReader textReader = new TextReader(new InputStreamResource(inputStream));List<Document> documents = textReader.get();// 文档拆分TextSplitterIntf textSplitter = new RecursiveCharacterTextSplitter(250, 30);List<Document> newDocuments = textSplitter.split(documents, List.of(Map.of(SpringAIConst.VectorStore.METADATA_DOC_ID, docHash,SpringAIConst.VectorStore.METADATA_DOC_NAME, docName)));// 向量入库vectorStore.add(newDocuments);// 将文档信息存入 RedisJSONObject docJson = new JSONObject();docJson.put(SpringAIConst.VectorStore.METADATA_DOC_NAME, docName);docJson.put("docSize", docSize);docJson.put("docChunks", newDocuments.size());redisService.setObject(CommonConst.RAG_KEY_PREFIX + docHash, docJson);}

6.5.2 计算文档的 Hash 值

支持的算法:MD5、SHA-1、SHA-256

    /*** 计算文件 Hash 值** @param inputStream 输入流* @param algorithm   算法,可选,MD5、SHA-1、SHA-256* @return* @throws Exception*/public static String calculateFileHash(InputStream inputStream, String algorithm) throws Exception {// 创建MessageDigest实例algorithm = StringUtils.isEmpty(algorithm) ? CommonConst.SHA_256 : algorithm;MessageDigest digest = MessageDigest.getInstance(algorithm);// 打开文件输入流try (inputStream) {byte[] buffer = new byte[1024];int numRead;// 读取文件内容并更新摘要while ((numRead = inputStream.read(buffer)) != -1) {digest.update(buffer, 0, numRead);}// 完成哈希计算byte[] hashBytes = digest.digest();// 将哈希值转换为十六进制字符串StringBuilder sb = new StringBuilder();for (byte b : hashBytes) {sb.append(String.format("%02x", b));}return sb.toString();}}

6.6 聊天接口

话不多说,直接上代码。

    /*** 带聊天记忆流式返回** @param accessKey 聊天访问key,每次打开聊天页面重置* @param inputInfo 聊天输入内容* @param docIds    参考文档ID,多个用英文','号隔开* @return*/@GetMapping("/memoryStreamWithApi")public Flux<ServerSentEvent<String>> memoryStreamWithApi(String accessKey, String inputInfo, String docIds) {// 接收并校验参数CommonUtil.checkAndThrow(accessKey, "您没有该功能访问权限!");CommonUtil.checkAndThrow(inputInfo, "请输入内容!");// 调用模型查询ChatClient.ChatClientRequestSpec chatClientRequestSpec = ChatClient.builder(chatModel).defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())).build().prompt().user(inputInfo).advisors(advisor -> advisor.param(CHAT_MEMORY_CONVERSATION_ID_KEY, accessKey).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 5));// 先从向量库查询近似数据if (StringUtils.isNotEmpty(docIds)) {// 组装过滤条件,根据文档ID过滤,等价于 SQL 的 WHERE docId IN (docId1,docId2...)List<String> docIdList = Arrays.asList(docIds.split(","));Filter.Expression expression = new Filter.Expression(Filter.ExpressionType.IN,new Filter.Key(SpringAIConst.VectorStore.METADATA_DOC_ID), new Filter.Value(docIdList));Advisor advisor = new QuestionAnswerAdvisor(vectorStore,SearchRequest.builder().query(inputInfo).filterExpression(expression).topK(6).similarityThreshold(0.8d).build());chatClientRequestSpec.advisors(advisor);}return chatClientRequestSpec.stream().chatResponse().map(response -> ServerSentEvent.<String>builder().data(response.getResult().getOutput().getContent()).build());}

7. 快速搭建 Elemenet-Plus 项目

写到这发现需要整理的文档太多,前端实现放到下一篇文章。

8. 参考文档

  • Spring AI RAG 文档
  • Spring AI Alibaba RAG 文档
  • Vue3 文档
  • Element Plus 文档
  • markdown-it 文档

9. 拓展

9.1 如何计算 Token ?

9.1.1 阿里通义

Token 是模型用来表示自然语言文本的基本单位,可以直观地理解为“字”或“词”。

  • 对于中文文本,1个 Token 通常对应一个汉字或词语。例如,“你好,我是通义千问”会被转换成['你好', ',', '我是', '通', '义', '千', '问']。

  • 对于英文文本,1个 Token 通常对应3至4个字母或1个单词。例如,"Nice to meet you."会被转换成['Nice', ' to', ' meet', ' you', '.']。

不同的大模型切分Token 的方法可能不同。可以本地运行 tokenizer 来估计文本的 Token 量。

9.1.2 DeepSeek

一般情况下模型中 token 和字数的换算比例大致如下:

  • 1 个英文字符 ≈ 0.3 个 token。

  • 1 个中文字符 ≈ 0.6 个 token。

相关文章:

【Spring AI】基于SpringAI+Vue3+ElementPlus的QA系统实现一

整理不易&#xff0c;请不要吝啬你的赞和收藏。 1. 前言 这是 SpringAI 系列的第二篇文章&#xff0c;这篇文章将介绍如何基于 RAG 技术&#xff0c;使用 SpringAI Vue3 ElementPlus 实现一个 Q&A 系统。本文使用 deepseek 的 DeepSeek-V3 作为聊天模型&#xff0c;使用…...

前端快速生成接口方法

大家好&#xff0c;我是苏麟&#xff0c;今天聊一下OpenApi。 官网 &#xff1a; umijs/openapi - npm 安装命令 npm i --save-dev umijs/openapi 在根目录&#xff08;项目目录下&#xff09;创建文件 openapi.config.js import { generateService } from umijs/openapi// 自…...

【Qt 常用控件】多元素控件(QListWidget、QTabelWidgt、QTreeWidget)

**View和**Widget的区别&#xff1f; **View的实现更底层&#xff0c;**Widget是基于**View封装实现的更易用的类型。 **View使用MVC结构 MVC是软件开发中 经典的 软件结构 组织形式&#xff0c;软件设计模式。 M&#xff08;model&#xff09;模型。管理应用程序的核心数据和…...

java 读取sq3所有表数据到objectNode

1.实现效果&#xff1a;将sq3中所有表的所有字段读到objectNode 对象中&#xff0c;兼容后期表字段增删情况&#xff0c;数据组织形式如下图所示&#xff1a; 代码截图&#xff1a; 代码如下&#xff1a; package com.xxx.check.util;import java.sql.*; import java.util.Arr…...

react redux用法学习

参考资料&#xff1a; https://www.bilibili.com/video/BV1ZB4y1Z7o8 https://cn.redux.js.org/tutorials/essentials/part-5-async-logic AI工具&#xff1a;deepseek&#xff0c;通义灵码 第一天 安装相关依赖&#xff1a; 使用redux的中间件&#xff1a; npm i react-redu…...

C++20中的std::atomic_ref

一、std::atomic_ref 我们在学习C11后的原子操作时&#xff0c;都需要提前定义好std::atomic变量&#xff0c;然后才可以在后续的应用程序中进行使用。原子操作的优势在很多场合下优势非常明显&#xff0c;所以这也使得很多开发者越来习惯使用原子变量。 但是&#xff0c;在实…...

encodeURI(),encodeURIComponent()区别

encodeURI()&#xff0c;encodeURIComponent()区别 encodeURI(): 对整个url(链接/网络链接)进行编码。 对中文&#xff0c;完全编码。 对英文不带空格则不会编码&#xff0c;带空格则会对空格编码。 解码&#xff1a;decodeURI() 例如&#xff1a; let ChineseUrl "htt…...

Selenium:网页frame与多窗口处理

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、多窗口处理 1.1、多窗口简介 点击某些链接&#xff0c;会重新打开⼀个窗⼜&#xff0c;对于这种情况&#xff0c;想在新页⾯上操作&#xff0c;就 得先切换窗…...

自动驾驶---如何打造一款属于自己的自动驾驶系统

在笔者的专栏《自动驾驶Planning决策规划》中&#xff0c;主要讲解了行车的相关知识&#xff0c;从Routing&#xff0c;到Behavior Planning&#xff0c;再到Motion Planning&#xff0c;以及最后的Control&#xff0c;笔者都做了相关介绍&#xff0c;其中主要包括算法在量产上…...

开源机器人+具身智能 解决方案+AI

开源机器人、具身智能(Embodied Intelligence)以及AI技术的结合,可以为机器人领域带来全新的解决方案。以下是这一结合的可能方向和具体方案: 1. 开源机器人平台 开源机器人平台为开发者提供了灵活的基础架构,可以在此基础上结合具身智能和AI技术。以下是一些常用的开源机…...

【web自动化】指定chromedriver以及chrome路径

selenium自动化&#xff0c;指定chromedriver&#xff0c;以及chrome路径 对应这篇文章&#xff0c;可以点击查看&#xff0c;详情 from selenium import webdriverdef get_driver():# 获取配置对象option webdriver.ChromeOptions()option.add_experimental_option("de…...

高等代数笔记—线性变换

latex花体字母与花体数字 https://blog.csdn.net/weixin_39589455/article/details/133846783 https://blog.csdn.net/orz_include/article/details/123645710线性变换 线性空间 V V V到自身的映射称为 V V V的一个变换&#xff0c;最基本的是线性变换。 定义&#xff1a;变换…...

Kickstart自动化安装过程中自动选择较小的磁盘安装操作系统

Kickstart自动化安装过程中自动选择较小的磁盘安装操作系统 需求 在实际生成操作过程中&#xff0c;一般会遇到物理服务器存在多块盘的情况。 安装过程中&#xff0c;磁盘的标签是随机分配的&#xff0c;并不是空间较小的盘&#xff0c;就会使用较小的磁盘标签 而需求往往需要…...

2024BaseCTF_week4_web上

继续&#xff01;冲冲冲 目录 圣钥之战1.0 nodejs 原型 原型链 原型链污染 回到题目 flag直接读取不就行了&#xff1f; 圣钥之战1.0 from flask import Flask,request import jsonapp Flask(__name__)def merge(src, dst):for k, v in src.items():if hasattr(dst, __geti…...

大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡

大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡 背景 前端开发接口请求&#xff0c;调试&#xff0c;联调&#xff0c;接入数据&#xff0c;前端必不可少工具&#xff0c;postman是一个非常好…...

内网穿透的应用-Ubuntu本地Docker搭建pichome文件管理系统打造个人云相册

文章目录 前言1.关于pichome2.本地部署pichome3.简单使用pichome4. 安装内网穿透5.配置pichome公网地址6. 配置固定公网地址 前言 你是不是也经常遇到这样的尴尬&#xff1a;手机、电脑里堆满了照片和视频&#xff0c;想找一张特定的图片时却像在大海捞针一样无从下手&#xf…...

深度学习之神经网络框架搭建及模型优化

神经网络框架搭建及模型优化 目录 神经网络框架搭建及模型优化1 数据及配置1.1 配置1.2 数据1.3 函数导入1.4 数据函数1.5 数据打包 2 神经网络框架搭建2.1 框架确认2.2 函数搭建2.3 框架上传 3 模型优化3.1 函数理解3.2 训练模型和测试模型代码 4 最终代码测试4.1 SGD优化算法…...

DeepSeek AI R1推理大模型API集成文档

DeepSeek AI R1推理大模型API集成文档 引言 随着自然语言处理技术的飞速发展&#xff0c;大语言模型在各行各业的应用日益广泛。DeepSeek R1作为一款高性能、开源的大语言模型&#xff0c;凭借其强大的文本生成能力、高效的推理性能和灵活的接口设计&#xff0c;吸引了大量开发…...

怎麼使用靜態住宅IP進行多社媒帳號管理

隨著社交媒體平臺的多樣化&#xff0c;很多人發現一個社媒帳號已經無法滿足需求。以下是幾個常見場景&#xff1a; 企業需求&#xff1a;企業可能需要在不同平臺上運營多個品牌帳號&#xff0c;為每個市場地區單獨設立帳號。個人需求&#xff1a;一些自由職業者或內容創作者可…...

【Elasticsearch】Bucket Selector Aggregation

Elasticsearch 的Bucket Selector Aggregation是一种强大的管道聚合功能&#xff0c;用于根据条件过滤聚合结果中的桶&#xff08;buckets&#xff09;。它允许用户通过编写脚本来动态决定哪些桶应该被保留&#xff0c;哪些应该被过滤掉。以下是对Bucket Selector Aggregation的…...

CEF132 编译指南 MacOS 篇 - 启程:认识 CEF (一)

1. 引言 在当今的软件开发领域&#xff0c;将 Web 技术融入桌面应用程序已成为一种趋势。开发者们寻求一种方式&#xff0c;既能充分利用原生应用的性能&#xff0c;又能享受 Web 开发带来的高效和灵活性。Chromium Embedded Framework (CEF) 应运而生&#xff0c;它是一个基于…...

Python 操作 MongoDB 教程

一、引言 在当今数字化时代&#xff0c;数据的存储和管理至关重要。传统的关系型数据库在处理一些复杂场景时可能会显得力不从心&#xff0c;而 NoSQL 数据库应运而生。MongoDB 作为一款开源的、面向文档的 NoSQL 数据库&#xff0c;凭借其高性能、高可扩展性和灵活的数据模型…...

长安汽车发布“北斗天枢2.0”计划,深蓝汽车普及全民智驾

2月9日&#xff0c;长安汽车智能化战略“北斗天枢2.0”计划暨深蓝汽车全场景智能驾驶解决方案发布会在重庆盛大召开。此次发布会标志着长安汽车正式迈入智能化战略的新纪元&#xff0c;携手众多“中国智驾合伙人”&#xff0c;共同开启全民智驾元年。 发布会上&#xff0c;长安…...

SpringBoot速成(七)注册实战P2-P4

1.创建 数据库创建 依赖引入 <!-- mybatis起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency> <…...

大语言模型RAG,transformer

1、RAG技术流总结 第一张图是比较经典的RAG知识图谱&#xff0c;第二张图是更加详细扎实的介绍图。 1.1 索引 坦白来说这部分的技术并不是大模型领域的&#xff0c;更像是之前技术在大模型领域的应用&#xff1b;早在2019年我就做过faiss部分的尝试&#xff0c;彼时索引技术已…...

Crowdin 在线本地化平台调用硅基流动AI预翻译

平台介绍 硅基流动&#xff08;AI服务平台&#xff09; 官网&#xff1a;https://siliconflow.cn/zh-cn/ 官方介绍 我主要使用&#xff1a;云服务平台 SilliconCloud 此平台已经将热门的开源大语言模型部署&#xff0c;花钱买额度&#xff0c;就能使用 API 最近有上线 Deep…...

第5章 数据库系统(选择|案例|论文)(重点★★★★★)

5.1 数据库管理系统1 数据库是长期存储在计算机内的、有组织的、可共享的数据集合&#xff0c;数据库系统是指在计算机信息系统中引入数据库后的系统&#xff0c;一般由数据库、数据库管理系统 (DataBaseManagement System&#xff0c;DBMS)、应用系统、数据库管理员(DataBase…...

linux部署node服务

1、安装nvm管理node版本 # 下载、解压到指定目录 wget https://github.com/nvm-sh/nvm/archive/refs/tags/v0.39.1.tar.gz tar -zxvf nvm-0.39.0.tar.gz -C /opt/nvm # 配置环境 vim ~/.bashrc~&#xff1a;这是一个路径简写符号&#xff0c;代表当前用户的主目录。在大多数 …...

【AI赋能】蓝耘智算平台实战指南:3步构建企业级DeepSeek智能助手

蓝耘智算平台实战指南&#xff1a;3步构建企业级DeepSeek智能助手 引言&#xff1a;AI大模型时代的算力革命 在2025年全球AI技术峰会上&#xff0c;DeepSeek-R1凭借其开源架构与实时推理能力&#xff0c;成为首个通过图灵测试的中文大模型。该模型在语言理解、跨模态交互等维…...

hyperf知识问题汇总

1、简单说下 hyperf&#xff08;什么是 hyperf&#xff09; 答&#xff1a;hyperf 是一个依赖swoole扩展的 php 开源开发框架&#xff0c;它由黄朝辉团队设计创建维护&#xff0c;具备简洁而强大的组件和超强的并发性能&#xff0c;而且还支持微服务架构&#xff0c;例如&…...

【EXCEL】【VBA】处理GI Log获得Surf格式的CONTOUR DATA

【EXCEL】【VBA】处理GI Log获得Surf格式的CONTOUR DATA data source1: BH coordination tabledata source2:BH layer tableprocess 1:Collect BH List To Layer Tableprocess 2:match Reduced Level from "Layer"+"BH"data source1: BH coordination…...

DeepSeek-R1技术革命:用强化学习重塑大语言模型的推理能力

引言&#xff1a;低成本高性能的AI新范式 在2025年1月&#xff0c;中国AI公司DeepSeek发布了两个标志性模型——DeepSeek-R1-Zero与DeepSeek-R1&#xff0c;以仅600万美元的训练成本实现了与OpenAI O1系列&#xff08;开发成本约5亿美元&#xff09;相当的推理性能&#xff0c…...

SQLite 约束

SQLite 约束 SQLite 是一种轻量级的数据库管理系统,它以其简洁的设计和高效的性能在众多数据库系统中脱颖而出。在SQLite中,约束是一种用于确保数据完整性和一致性的机制。本文将详细介绍SQLite中的各种约束,包括它们的用途、语法以及在实际应用中的注意事项。 1. 约束概述…...

Vue.js 状态管理库Pinia

Pinia Pinia &#xff1a;Vue.js 状态管理库Pinia持久化插件-persist Pinia &#xff1a;Vue.js 状态管理库 Pinia 是 Vue 的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态。 要使用Pinia &#xff0c;先要安装npm install pinia在main.js中导入Pinia 并使用 示例…...

qwen2.5-vl-7B视觉大模型 私有化部署webUI

服务器选用&#xff1a;算力云 部署qwen2.5-vl-7B&#xff0c;24g显卡跑不起图&#xff0c;单问问题就占20g左右。有能力可以用大点的显卡 一、下载模型 Qwen2.5-VL-7B-Instruct 有conda &#xff0c;可以在conda下操作&#xff0c;不知道conda的同学可以参考本博主之前的文章…...

Spring Boot 线程池自定义拒绝策略:解决任务堆积与丢失问题

如何通过自定义线程池提升系统稳定性 背景 在高并发系统中&#xff0c;线程池管理至关重要。默认线程池可能导致&#xff1a; 资源浪费&#xff08;创建过多线程导致 OOM&#xff09;任务堆积&#xff08;队列满后任务被拒绝&#xff09;任务丢失&#xff08;默认拒绝策略丢…...

C++17 新特性解析

C++17 是 C++ 标准的一个重要更新,它在 C++11/14 的基础上引入了许多新特性,进一步简化了代码编写、提升了性能和类型安全性。以下是 C++17 的主要特性分类介绍: 一、语言核心改进 1. 结构化绑定(Structured Bindings) 允许将元组、结构体或数组的成员直接解包到变量中。…...

支持向量机相关文献

根据最新的研究动态和文献综述&#xff0c;当前支持向量机&#xff08;SVM&#xff09;的研究方向和内容主要集中在以下几个方面&#xff1a; 1. 提高训练效率 并行计算与分布式计算&#xff1a;随着数据规模的增加&#xff0c;SVM的训练时间往往较长&#xff0c;难以满足实时…...

线上hbase rs 读写请求个数指标重置问题分析

问题描述: 客户想通过调用hbase的jmx接口获取hbase的读写请求个数,以此来分析HBase读写请求每日增量。 但是发现生产,测试多个集群,Hbase服务指标regionserver读写请求个数存在突然下降到0或者大幅度下降情况。 需要排查原因: 某个Region的读写请求数:会发现经常会重置为…...

USB子系统学习(四)用户态下使用libusb读取鼠标数据

文章目录 1、声明2、HID协议2.1、描述符2.2、鼠标数据格式 3、应用程序4、编译应用程序5、测试6、其它 1、声明 本文是在学习韦东山《驱动大全》USB子系统时&#xff0c;为梳理知识点和自己回看而记录&#xff0c;全部内容高度复制粘贴。 韦老师的《驱动大全》&#xff1a;商…...

WPF 设置宽度为 父容器 宽度的一半

方法1&#xff1a;使用 绑定和转换器 实现 创建类文件 HalfWidthConverter public class HalfWidthConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){if (value is double width){return width / 4…...

网络工程师 (30)以太网技术

一、起源与发展 以太网技术起源于20世纪70年代&#xff0c;最初由Xerox公司的帕洛阿尔托研究中心&#xff08;PARC&#xff09;开发。最初的以太网采用同轴电缆作为传输介质&#xff0c;数据传输速率为2.94Mbps&#xff08;后发展为10Mbps&#xff09;&#xff0c;主要用于解决…...

2025.2.11

1> 制作一个闹钟软件 .h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QTime> #include <QTimer> #include <QTimeEdit> #include <QDa…...

HTML应用指南:利用POST请求获取接入比亚迪业态的充电桩位置信息

在新能源汽车快速发展的今天,充电桩的分布和可用性成为了影响用户体验的关键因素之一。比亚迪作为全球领先的新能源汽车制造商,不仅在车辆制造方面取得了卓越成就,也在充电基础设施建设上投入了大量资源。为了帮助用户更方便地找到比亚迪充电桩的位置,本篇文章,我们将探究…...

系统URL整合系列视频四(需求介绍补充)

视频 系统URL整合系列视频四&#xff08;需求补充说明&#xff09; 视频介绍 &#xff08;全国&#xff09;大型分布式系统Web资源URL整合需求&#xff08;补充&#xff09;讲解。当今社会各行各业对软件系统的web资源访问权限控制越来越严格&#xff0c;控制粒度也越来越细。…...

PRC框架-Dubbo

RPC框架 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;框架是一种允许客户端通过网络调用服务器端程序的技术。以下是常见的RPC框架及其特点&#xff1a; 1. 基于HTTP/REST的RPC框架 特点&#xff1a;简单易用&#xff0c;与Web开发无缝集成&am…...

Win10环境借助DockerDesktop部署最新MySQL9.2

Win10环境借助DockerDesktop部署最新MySQL9.2 前言 作为一杆主要撸Java的大数据平台开发攻城狮&#xff0c;必不可少要折腾各种组件&#xff0c;环境和版本一直是很头疼的事情。虽然可以借助Anaconda来托管Python的环境&#xff0c;也可以使用多个虚拟机来部署不同的环境&…...

PlantUML 总结

PlantUML 总结 1. 概述 PlantUML 是一个开源工具&#xff0c;允许用户通过简单的文本描述来生成各种UML图表。它支持多种图表类型&#xff0c;包括但不限于序列图、用例图、类图、活动图等。 2. 基本概念 2.1 开始和结束标记 startuml 和 enduml&#xff1a;用于标记Plant…...

【Elasticsearch】监控与管理:集群监控指标

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

Swift的方法派发机制

1. 静态派发&#xff08;Static Dispatch&#xff09; 静态派发在编译时确定方法的具体实现&#xff0c;调用时直接跳转到该实现。静态派发的优点是性能高&#xff0c;因为不需要运行时查找方法实现。 适用场景&#xff1a; 值类型&#xff08;Struct 和 Enum&#xff09;&am…...