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

深度学习:基于MindNLP的RAG应用开发

什么是RAG?

RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合检索(Retrieval)和生成(Generation)的技术,旨在提升大语言模型(LLM)生成内容的准确性、相关性和时效性。

  • 基本思想:通过外部知识库动态检索与用户查询相关的信息,并将检索结果作为上下文输入生成模型,辅助生成更可靠的回答。

  • 与传统LLM的区别:传统LLM仅依赖预训练参数中的静态知识,而RAG能实时利用外部数据,解决模型幻觉(编造信息)和知识过时的问题。

RAG分为两阶段流程:

  1. 检索阶段(Retrieval)

    • 将用户查询转换为向量或关键词,从外部知识库(如文档、数据库、网页)中检索相关内容。

    • 常用技术:向量数据库(如FAISS)、BM25算法、语义相似度匹配。

  2. 生成阶段(Generation)

    • 将检索到的信息与用户输入拼接,输入生成模型(如GPT、LLaMA)生成最终回答。

    • 模型结合检索内容与自身知识,生成更精准、可解释的响应。

为什么需要RAG?

一、突破静态知识的限制

  1. 知识过时
    模型训练完成后无法自动更新知识(如GPT-3的数据截止到2021年)。
    示例:若用户询问“2023年诺贝尔奖得主是谁”,传统模型无法回答,而RAG可通过检索最新新闻或数据库提供正确答案。

  2. 覆盖范围有限
    模型对长尾领域(如企业内部文档、专业论文)或小众问题(如特定设备故障代码)可能缺乏知识。

二、减少模型“幻觉”风险

大模型生成内容时可能编造看似合理但错误的信息(称为“幻觉”),这在关键场景(如医疗、法律)中风险极高。

三、无需重新训练,低成本扩展能力

传统方法需通过微调(Fine-tuning) 让模型适配新任务,但存在痛点:

  1. 数据需求高:需大量标注数据,成本高昂。

  2. 难以频繁更新:每次更新知识都需重新训练模型,效率低下

RAG的优势:

  • 动态扩展知识:仅需更新外部知识库(如上传最新文档),无需修改模型参数。
  • 灵活适配场景:同一模型可连接不同知识库,服务医疗、金融等多个领域。

RAG的工作流程

一、构建知识库

1. 文本分块:将长篇文档切分为多个文本块,一边更加高效地处理和检索信息。

2. 向量化:使用各种Embedding模型来将每个文本块转换为高纬向量表示,使得文本之间可以在高维空间中进行相似度比较和检索。

二、用户检索

1. 向量化:将用户提出的问题,经过同样的向量化处理,得到问题的向量表示。

2. 检索:通过向量数据库进行相似性检验(如余弦相似度),从知识库中找到与用户提问相关的文档切片。

3. 响应:将检索到的文本块作为额外的上下文,加上用户的问题,生成更加规范正确的答案。

基于Mindspore的RAG实现

首先,需要在ModelArts平台创建:mindspore == 2.3.0, cann == 8.0.0的notebook。

随后,克隆github项目:

克隆MindNLP并更新

git clone https://github.com/mindspore-lab/mindnlp.git
cd mindnlp
git checkout ef64a3b83097c9578bb0d5326f905beeb5b50e1d
bash scripts/build_and_reinstall.sh

RAG项目

git clone https://github.com/ResDream/MindTinyRAG.git

安装所需依赖

cd MindTinyRAG
pip install -r requirements.txt

一、 读取文件与处理

需求分析:

  • 文件格式不同,需要判断文件类型再进行内容提取。
  • 基于最大token长度和覆盖内容的逻辑分割长文本,确保段落间的语义连续性。
分块策略

1. 固定长度分块(Fixed-Size Chunks)

将文档按固定长度(如每段100字或500字符)均匀切割。

优点:实现简单,计算高效。适合结构化文本(如代码、表格)。

缺点:可能破坏句子或段落的语义完整性。对长距离依赖的上下文不敏感。

示例:

原文:人工智能(AI)是... [100字] → 分块1:人工智能(AI)是...;分块2:在医疗领域...;

2. 基于内容的分块(Content-Based Chunking)

根据文档结构(段落、标题、分隔符)进行分块。

常见方法

  • 段落分块:以自然段落为单位。
  • 标题分块:按标题层级切分(如H1、H2)。
  • 分隔符分块:根据标点(如句号)、空行或Markdown符号(##)分割。

优点:保留语义单元,减少上下文碎片化。适合非结构化文本(如文章、报告)。

缺点:依赖文档格式的规范性(如无明确分隔符时失效)。

示例:

# 第一章 引言
人工智能是... → 分块1(标题+段落)
## 1.1 发展历史
20世纪50年代... → 分块2

3. 滑动窗口分块(Sliding Window)

在固定长度分块基础上,通过重叠窗口(如50%重叠)连接上下文。

优点:缓解固定分块导致的上下文断裂问题。提升相邻块之间的语义连贯性。

缺点:增加存储和计算成本(块数量翻倍)。

示例:

窗口大小=200字符,重叠=50%  
分块1:字符1-200  
分块2:字符100-300  
分块3:字符200-400

4. 语义分块(Semantic Chunking)

利用NLP模型(如句子嵌入、文本分割模型)识别语义边界。

常用技术

  • 句子分割:按完整句子分块。
  • 主题分割:检测文本主题变化(如使用TextTiling算法)。
  • 嵌入聚类:通过向量相似度合并相关段落。

优点:保持语义完整性,适合长文本(如论文、书籍)。提升检索相关性。

缺点:计算复杂度高,依赖模型性能。

示例

原文:深度学习在CV中的应用...(技术细节)。另一方面,NLP领域... → 分块1(CV)、分块2(NLP)

5. 动态分块(Dynamic Chunking)

据查询需求动态调整分块粒度。

实现方式

  • 多粒度索引:同时存储不同粒度的块(如段落、章节、全文)。
  • 检索时合并:检索到多个相关小粒度块后合并为上下文。

优点:平衡召回率与噪声控制。适应多样化的查询需求。

缺点:系统设计复杂,需多层索引支持。

分块策略选择建议
  1. 平衡长度与语义

    • 一般场景:优先语义分块(如段落)或滑动窗口(重叠20-30%)。

    • 长文本(如书籍):语义分块+动态合并。

  2. 考虑下游模型限制

    • 块长度需适配生成模型的输入容量(如GPT-4最大支持128k tokens)。

  3. 领域适配

    • 技术文档:按函数/API分块;法律文本:按条款分块。

  4. 实验调优

    • 通过检索准确率、生成质量等指标测试最佳分块大小。

项目使用滑动窗口分块策略:

  • 分块大小(chunk size):定义每个分块的最大长度,通常以token为单位
  • 滑动步长(stride size):定义分块的起始位置之间的距离,从而实现分块之间的重叠。
  • 重叠内容(overlap):由 | chunk size - stride size | 决定,用于保留上下文

1. 确定每个文本块的最大长度(分块大小)

2. 确定滑动的步长,计算分块之间的重叠区域

3. 从文档头开始,提取长度为窗口大小的内容作为分块

4. 从前一个分块的起始位置向前滑动步长,提取下一段内容

5. 重复步骤4直至处理完整个文档。

定义ReadFile类:
# 定义读取文件的类
class ReadFiles:'''class for reading files with suffixes'''def __init__(self, path: str) -> None:'''path: 知识库的文件路径file_list:文件对象的列表'''self._path = pathself.file_list = self.get_files()@classmethoddef read_pdf(cls, file_path: str) -> str:'''使用PyPDF读取pdf文件,并返回文件中文本的方法param:file_path: 文件路径return:text: PDF中的所有文本'''with open(file_path, 'rb') as file:reader = PyPDF2.PdfReader(file)text = ''for page_num in range(len(reader.pages)):text += reder.pages[page_num].extract_text()return text@classmethoddef read_markdown(cls, file_path) -> str:'''使用bs4读取md文件,并返回文件中文本的方法param:file_path: 文件路径return:text: PDF中的所有文本'''with open(file_path, 'r', encoding='utf-8') as file:md_text = file.read()html_text = markdown.markdown(md_text)soup = BeautifulSoup(html_text, 'html.parser')plain_text = soup.get_text()# 使用正则表达式移除网址链接text = re.sub(r'http\S+', '', plain_text) return text@classmethoddef read_txt(cls, file_path: str) -> str:'''返回文件中文本的方法param:file_path: 文件路径return:text: 文件文本'''with open(file_path, 'r', encoding='utf-8') as file:text = file.read()return textdef get_files(self) -> list[str]:'''获取指定路径下的所有文件return:file_list:可以进行解析的所有文件的文件路径'''file_list =[]for filepath, dirnames, filenames in os.walk(self._path):# os.walk 函数将递归遍历指定文件夹for filename in filenames:# 通过后缀名判断是否能进行解析if filename.endswith('.md'):file_list.append(os.path.join(filepath, filename))elif filename.endswith('.txt'):file_list.append(os.path.join(filepath, filename))elif filename.endswith(".pdf"):file_list.append(os.path.join(filepath, filename))return file_listdef get_content(self, max_token_len: int = 600, cover_content: int = 150) -> list[str]:'''获取知识库中所有文件的文件内容param:max_token_len: 分块大小cover_conten: 重叠内容大小return:docs: 文件内容'''docs = []for file in self.file_list:# 获取文件内容content = self.read_file_content(file)# 将文件内容分块chunk_content = self.get_chunk(content, max_token_len=max_token_len, cover_content=cover_content)docs.extend(chunk_content)return docs@classmethoddef get_chunk(cls, text: str, max_token_len: int = 600, cover_content: int = 150):chunk_text = []# 当前块长度curr_len = 0# 当前块内容curr_chunk = ''# 滑动窗口的滑动步长token_len = max_token_len - cover_content# 假设以换行符对文本进行分割lines = text.splitlines()for line in lines:# 去除文本中的空格line = line.replace(' ', '')# enc.encode: 将文本转换为 token ID 列表line_len = len(enc.encode(line))# 如果文本较长,对文本进行分块(处理超长行)if line_len > max_token_len:# 计算一共要切成多少个文本块num_chunks = (line_len + token_len - 1) // token_lenfor i in range(num_chunks):start = i * token_lenend = start + token_len# 确保每个块的结尾不会截断一个完整的单词,从而保持语义的连贯性。# 通过循环逐步右移切割点,直到块末尾落在空白字符处:# 如果末尾不是空白,将 start 和 end 右移一位,直到满足条件或越界。while not line[start: end].rstrip().isspace():start += 1end += 1if start >= line_len:break# 前一个块的末尾 cover_content 字符与当前切割内容拼接:curr_chunk = curr_chunk[-cover_content: ] + line[start: end]chunk_text.append(curr_chunk)# 处理最后一个块# 循环内的 end 可能超出文本实际长度,需要单独处理最后一个块以修正范围。start = (num_chunks - 1) * token_lencurr_chunk = curr_chunk[-cover_content:] + line[start:end]chunk_text.append(curr_chunk)# 如果不是超长文本,直接处理# 如果当前文本还没有到达最长长度,先拼接,不添加if curr_len + line_len <= token_len:curr_chunk += linecurr_chunk += '\n'curr_len += line_lencurr_len += 1# 如果达到最长长度,直接添加else:chunk_text.append(curr_chunk)curr_chunk = curr_chunk[-cover_content: ] + linecurr_len = line_len + cover_contentif curr_chunk:chunk_text.append(curr_chunk)return chunk_text@classmethoddef read_file_content(cls, file_path: str):# 根据文件扩展名选择读取方法if file_path.endswith('.pdf'):return cls.read_pdf(file_path)elif file_path.endswith('.md'):return cls.read_markdown(file_path)elif file_path.endswith('.txt'):return cls.read_text(file_path)else:raise ValueError("Unsupported file type")

重点:get_chunk算法

该分块算法的核心实现思路可总结为以下流程:

首先基于换行符将原始文本分割为行级单位,假设“行”是天然语义边界;随后逐行处理时,针对两种场景采取不同策略。

普通行通过动态累加至当前块(curr_chunk),若累计 token 长度(curr_len)超出步长限制(token_len = max_token_len - cover_content),则将当前块存入结果并基于重叠机制(保留末尾 cover_content 字符)初始化新块

超长行则按步长预切割后,通过逐字符右移切割点使块末尾落于空格处,避免单词截断,同时每个新块强制拼接前一块的重叠内容以维持上下文连贯性。

算法通过隐式覆盖(非显式重置)管理状态变量,最终保证所有块长度不过 max_token_len 且相邻块间存在可控重叠。其优势在于平衡了切割效率与语义完整性,但需注意空格删除对语义的破坏风险及冗余块处理问题,可通过反向空格查找、精确换行符 token 计算和状态隔离进一步优化。

二、定义Embedding类

# Embedding设计
class BaseEmbeddings:'''embedding的基类'''def __init__(self, path: str, is_api: bool) -> None:self.path = pathself.is_api = is_apidef get_embedding(self, text: str, model: str) -> list[float]:'''待子类实现此方法'''raise NotImplementedErrort@classmethoddef consine_similarity(cls, vector1: list[float], vector2: list[float]) -> float:'''计算两个向量的余弦相似度'''dot = np.dot(vector1, vector2)magnitude = np.linalg.norm(vector1) * np.linalg.norm(vector2)if not magnitude:return 0return dot / magnitude
class MindNLPEmbedding(BaseEmbeddings):'''MindNLP使用的Embedding类,继承了BaseEmbedding'''def __init__(self, path='BAAI/bge-base-zh-v1.5', is_api=False):super().__init__(path, is_api)self._model = self.load_model(path)def get_embedding(self, text: str):'''使用定义的Embedding模型,获取输入句子的Embedding'''sentence_embedding = self._model.encode([text], normalize_embeddings=True)return sentence_embeddingdef load_model(self, path: str):'''通过MindNLP提供的类,加载Embedding模型并返回'''from mindnlp.sentence import SentenceTransformermodel = SentenceTransformer(path)return model@classmethoddef consine_similarity(cls, sentence_embedding_1, sentence_embedding_2):'''重写父类的相似度方法子类在调用 self._model.encode 时设置了 normalize_embeddings=True,这会强制将输出向量归一化为单位长度(模长为 1)。所以相似度只需要计算点积结果即可表示。'''similarity = sentence_embedding_1 @ sentence_embedding_2.Treturn similarity

三、知识库设计

向量数据库(Vector Database)是一种专门用于存储、管理和高效检索高维向量数据的数据库系统。它的核心目标是解决传统数据库难以处理的大规模高维数据相似性搜索问题,广泛应用于人工智能、机器学习和大数据领域。

常用的向量数据库有Meta AI团队提供的FAISS或华为的GaussDB for Vector

本案例将自己实现一个简单的向量数据库。

需求分析:

  1. Embedding计算
  2. 数据持久化存储
  3. 从文件中加载数据
  4. 相似文档查询
class VectorStore:def __init__(self, document: list[str] = ['']):'''初始化向量库param:document: 所有已经分块好的文本块'''self.document = documentdef get_vector(self, EmbeddingModel: BaseEmbeddings):'''获取所有文本块的向量'''self.vetors = []for doc in tqdm(self.document, desc='Calculating Embeddings'):# 通过Embedding类中定义好的方法,获取每个文本块的向量self.vetors.append(EmbeddingModel.get_embedding(doc))return self.vetorsdef persits(self, path: str = 'storage'):'''将向量数据保存到本地'''if not os.path.exists(path):os.makedirs(path)# 持久化存储文档with open(f"{path}/document.json", 'w', encoding='utf-8') as f:json.dump(self.document, f ,ensure_ascii=False)# 持久化存储向量if self.vetors:vectors_list = [vector.tolist() for vector in self.vetors]with open(f"{path}/vectors.json", 'w', encoding='utf-8') as f:json.dump(vectors_list, f)def load_vector(self, EmbeddingModel: BaseEmbeddings, path: str = 'storage'):with open(f"{path}/document.json", 'r', encoding='utf-8') as f:self.document = json.load(f)with open(f"{path}/vectors.json", 'r', encoding='utf-8') as f:vectors_list = json.load(f)# 判断EmbeddingModel的类型if isinstance(EmbeddingModel, MindNLPEmbedding):self.vetors = [np.array(vector) for vector in vectors_list]else:self.vetors = vectors_listdef get_similarity(self, query: str, EmbeddingModel: BaseEmbeddings, k: int = 1):# 获取query的向量query_vector = EmbeddingModel.get_embedding(query)# 计算查询向量和所有文本块的相似度similaraties = [self.get_similarity(query_vector, vector) for vector in self.vetors]# 将相似度、向量和文档存储在一个列表中results = []for similarity, vector, document in zip(similaraties, self.vetors, self.document):results.append({'similarity': similarity,'vector': vector,'document': document})# 将结果按照相似度降序排序results.sort(key=lambda x: x['similarity'], reverse=True)# 选取相似度最高的top_k个结果top_k_documents  = [result['document'] for result in results[:k]]return top_k_documents

四、定义模型

# 定义语言模型
class BaseModel:def __init__(self, path: str = ''):self.path = pathdef chat(self, prompt: str, history: list[dict], content: str) -> str:passdef load_model(self):pass# 定义prompt模板
PROMPT_TEMPLATE = dict(RAG_PROMPT_TEMPALTE="""使用以上下文来回答用户的问题。如果你不知道答案,请输出我不知道。总是使用中文回答。问题: {question}可参考的上下文:···{context}···如果给定的上下文无法让你做出回答,请回答数据库中没有这个内容,你不知道。有用的回答:""",MindNLP_PROMPT_TEMPALTE="""先对上下文进行内容总结,再使用上下文来回答用户的问题。如果你不知道答案,请输出我不知道。总是使用中文回答。问题: {question}可参考的上下文:···{context}···如果给定的上下文无法让你做出回答,请回答数据库中没有这个内容,你不知道。有用的回答:"""
)class MindNLPChat(BaseModel):def __init__(self, path: str = ''):super().__init__(path)self.load_model()def chat(self, prompt: str, history: list = [], content: str = '') -> str:"""生成对话回复。Args:prompt (str): 用户输入的提示文本。history (list[dict]): 对话历史,每个元素为包含'user'和'assistant'键的字典。content (str): 上下文内容,用于增强生成的相关性。Returns:str: 模型生成的回复文本。"""prompt = PROMPT_TEMPLATE['MindNLP_PROMPT_TEMPALTE'].format(question=prompt, context=content)resp, history = self.model.chat(self.tokenizer, prompt, history=history, max_length=1024)return respdef load_model(self):import mindsporefrom mindnlp.transformers import AutoTokenizer, AutoModelForCausalLMself.tokenizer = AutoTokenizer.from_pretrained(self.path, mirror="huggingface")self.model = AutoModelForCausalLM.from_pretrained(self.path, ms_dtype=mindspore.float16, mirror="huggingface")

五、重排序ReRank

Rerank(重排序)技术是优化检索结果的关键环节。它的核心目标是从初步检索得到的候选文档中,筛选出最相关、高质量的文档作为生成模型的输入,从而提升最终答案的准确性和相关性。

在RAG的典型流程中,Rerank位于检索(Retrieval)生成(Generation)之间:

  1. 检索阶段:使用快速但粗粒度的检索模型(如BM25、双编码器Bi-Encoder)从海量文档中召回Top-K候选(例如K=100)。

  2. Rerank阶段:对Top-K候选进行精细排序,选出最相关的Top-N(例如N=5)文档。

  3. 生成阶段:基于Top-N文档生成最终答案。

class MindNLPReranker(BaseReranker):def __init__(self, path: str = 'BAAI/bge-reranker-base'):super().__init__(path)self._model = self.load_model(path)def load_model(self, path: str):from mindnlp.sentence import SentenceTransformermodel = SentenceTransformer(path)return modeldef rerank(self, text, content, k):query_embedding = self._model.encode(text, normalize_embeddings=True)sentences_embedding = self._model.encode(content, normalize_embeddings=True)similarity = query_embedding @ sentences_embedding.T# 根据相似度降序排序reanked_index = np.argsort(similarity)[::-1]# 选择top k个结果top_k = [content[i] for i in reanked_index[:k]]return top_k# 创建RerankerModel
reranker = MindNLPReranker('BAAI/bge-reranker-base')
# 从向量数据库中查询出最相似的3个文档
content = vector.query(question, EmbeddingModel=embedding, k=3)
print('first query', content)
# 从一阶段查询结果中用Reranker再次筛选出最相似的2个文档
rerank_content = reranker.rerank(question, content, k=2)
print('reranked', rerank_content)# 最后选择最相似的文档, 交给LLM作为可参考上下文
best_content = rerank_content[0]
print(chat.chat(question, [], best_content))

运行代码:

embedding = MindNLPEmbedding("BAAI/bge-base-zh-v1.5")
vector = VectorStore(text)
vector.get_vector(EmbeddingModel=embedding)
vector.persists(path='storage')  # 将向量和文档内容保存到storage目录下,下次再用就可以直接加载本地的数据库
vector.load_vector(EmbeddingModel=embedding, path='./storage')  # 加载本地的数据库# 创建RerankerModel
reranker = MindNLPReranker('BAAI/bge-reranker-base')
# 从向量数据库中查询出最相似的3个文档
content = vector.query(question, EmbeddingModel=embedding, k=3)
print('first query', content)
# 从一阶段查询结果中用Reranker再次筛选出最相似的2个文档
rerank_content = reranker.rerank(question, content, k=2)
print('reranked', rerank_content)# 最后选择最相似的文档, 交给LLM作为可参考上下文
best_content = rerank_content[0]
print(chat.chat(question, [], best_content))

相关文章:

深度学习:基于MindNLP的RAG应用开发

什么是RAG&#xff1f; RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09; 是一种结合检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#xff09;的技术&#xff0c;旨在提升大语言模型&#xff08;LLM&#xff09;生…...

Hive安装教程

Hive安装教程 文章目录 Hive安装教程写在前面安装下载安装部署安装Hive启动并使用Hive MySQL安装检查当前系统是否安装过MySQL安装初始化数据库 Hive元数据配置到MySQL拷贝驱动配置Metastore到MySQL再次启动Hive 写在前面 Linux版本&#xff1a;CentOS7.5Hive版本&#xff1a;…...

安卓逆向之脱壳-认识一下动态加载 双亲委派(二)

一&#xff1a;动态加载与双亲委派模型 在 Java 和 Android 中&#xff0c;ClassLoader 是一个非常重要的组件&#xff0c;负责将 .class 文件或 .dex 文件的字节码加载到内存中&#xff0c;供程序使用。在这其中&#xff0c;有两种关键的概念需要深入理解&#xff1a;动态加载…...

全程Kali linux---CTFshow misc入门(14-24)

第十四题&#xff1a; dd命令&#xff1a;dd是一个用于复制和转换数据的命令&#xff0c;它可以对文件、设备等进行操作&#xff0c;在数据备份、转换格式等场景经常使用。 ifmisc14.jpg&#xff1a;if表示 “input file”&#xff08;输入文件&#xff09;&#xff0c;这里指…...

学习数据结构(3)顺序表

1.动态顺序表的实现 &#xff08;1&#xff09;初始化 &#xff08;2&#xff09;扩容 &#xff08;3&#xff09;头部插入 &#xff08;4&#xff09;尾部插入 &#xff08;5&#xff09;头部删除 &#xff08;这里注意要保证有效数据个数不为0&#xff09; &#xff08;6&a…...

知识体系、知识管理角度的赚钱思考

从知识管理和知识体系的角度出发&#xff0c;赚钱的问题思考清单可以帮助你系统地梳理和优化自己在财富创造方面的策略。 以下是一个详细的清单&#xff0c;涵盖从知识获取、技能提升到实际应用的各个环节&#xff0c;帮助你在赚钱的道路上更加高效和有条理。 一、赚钱的目标与…...

(done) ABI 相关知识补充:内核线程切换、用户线程切换、用户内核切换需要保存哪些寄存器?

由于操作系统和编译器约定了 ABI&#xff0c;如下&#xff1a; 编译器在对 C 语言编译时&#xff0c;会自动 caller 标注的寄存器进行保存恢复。保存的步骤通常发生在进入函数的时候&#xff0c;恢复的步骤通常发生在从函数返回的时候。 内核线程切换需要保存的寄存器&#…...

QT6 + CMAKE编译OPENCV3.9

参考文档 [1] https://blog.csdn.net/rjkf_css/article/details/135676077 前提条件 配置好相关运行环境&#xff1a;QT6、OPENCV3.9的sources文件 OPENCV下载网页&#xff1a;https://opencv.org/releases/ QT6下载教程&#xff1a;https://blog.csdn.net/caoshangpa/article…...

Linux 常用命令——系统设置篇(保姆级说明)

系统设置类 显示当前运行的进程&#xff08;ps&#xff09; ps [options] [--help]# 查找指定进程格式&#xff1a; ps -ef | grep 进程关键字# 显示进程信息 ps -A 参数&#xff1a; -A 列出所有的进程 -w 显示加宽可以显示较多的资讯 -au 显示较详细的资讯 -aux 显示所有包…...

完美世界前端面试题及参考答案

如何设置事件捕获和事件冒泡? 在 JavaScript 中,可以通过addEventListener方法来设置事件捕获和事件冒泡。该方法接收三个参数,第一个参数是事件类型,如click、mousedown等;第二个参数是事件处理函数;第三个参数是一个布尔值,用于指定是否使用事件捕获机制。当这个布尔值…...

Vue3笔记——(三)hooks、路由

015 hooks 作用&#xff1a;使得代码更加模块化和可维护 Person.vue <template><div><h2>当前求和{{ sum }}</h2><button click"addFn">点我sum1</button></div> </template> <script setup lang"ts"…...

网络安全大模型和人工智能场景及应用理解

本文通过通俗易懂的方式的进行阐述&#xff0c;大家读完觉得有帮助记得及时关注和点赞&#xff01;&#xff01;&#xff01; 一、网络安全大模型的概述 网络安全大模型是一种用于识别和应对各种网络安全威胁的模型。它通过分析网络数据包、网络行为等信息&#xff0c;识别潜在…...

python-leetcode-从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right r…...

NLP模型大对比:Transformer > RNN > n-gram

结论 Transformer 大于 RNN 大于 传统的n-gram n-gram VS Transformer 我们可以用一个 图书馆查询 的类比来解释它们的差异&#xff1a; 一、核心差异对比 维度n-gram 模型Transformer工作方式固定窗口的"近视观察员"全局关联的"侦探"依赖距离只能看前…...

MySQL查询优化(三):深度解读 MySQL客户端和服务端协议

如果需要从 MySQL 服务端获得很高的性能&#xff0c;最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些&#xff0c;大部分的查询优化是有据可循的&#xff0c;从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程&#xff1a; 客户端…...

[STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器

一、高级定时器简介 高级定时器的简介在前面一章已经介绍过&#xff0c;可以点击下面链接了解&#xff0c;在这里进行一些补充。 [STM32 - 野火] - - - 固件库学习笔记 - - -十二.基本定时器 1.1 功能简介 1、高级定时器可以向上/向下/两边计数&#xff0c;还独有一个重复计…...

Antd React Form使用Radio嵌套多个Select和Input的处理

使用Antd React Form使用Radio会遇到嵌套多个Select和Input的处理&#xff0c;需要多层嵌套和处理默认事件和冒泡&#xff0c;具体实现过程直接上代码。 实现效果布局如下图 代码 <Formname"basic"form{form}labelWrap{...formItemLayoutSpan(5, 19)}onFinish{on…...

固有频率与模态分析

目录 引言 1. 固有频率&#xff1a;物体的“天生节奏” 1.1 定义 1.2 关键特点 1.3 实际意义 2. 有限元中的模态分析&#xff1a;给结构“体检振动” 2.1 模态分析的意义 2.2 实际案例 2.2.1 桥梁模态分析 2.2.2 飞机机翼模态分析 2.2.3 具体事例 3. 模态分析的工具…...

视频多模态模型——视频版ViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》&#xff0c;2021由google 提出用于视频处理的视觉 Transformer 模型&#xff0c;在视频多模态领域有…...

2859.计算K置位下标对应元素的和

示例 1&#xff1a;输入&#xff1a;nums [5,10,1,5,2], k 1 输出&#xff1a;13 解释&#xff1a;下标的二进制表示是&#xff1a; 0 0002 1 0012 2 0102 3 0112 4 1002 下标 1、2 和 4 在其二进制表示中都存在 k 1 个置位。 因此&#xff0c;答案为 nums[1] nums[…...

Redis 教程

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 它通常被称为数据结构服务器&…...

2024 CVPR Highlight Learning-Feedback

图像增强 Towards Robust Event-guided Low-Light Image Enhancement: A Large-Scale Real-World Event-Image Dataset and Novel Approach 解决的主要问题是低光照条件下的图像增强 通过多尺度整体融合分支提取事件和图像的结构和纹理信息&#xff0c;并引入信噪比&#xff0…...

maven、npm、pip、yum官方镜像修改文档

文章目录 Maven阿里云网易华为腾讯云 Npm淘宝腾讯云 pip清华源阿里中科大华科 Yum 由于各博客繁杂&#xff0c;本文旨在记录各常见镜像官网&#xff0c;及其配置文档。常用镜像及配置可评论后加入 Maven 阿里云 官方文档 setting.xml <mirror><id>aliyunmaven&l…...

UE求职Demo开发日志#15 思路与任务梳理、找需要的资源

1 思路梳理 因为有点无从下手&#xff0c;就梳理下最终形态. 基地的建设我是想单独一个场景&#xff0c;同一个关卡中小怪会每次来都会刷&#xff0c;小解密一次性的&#xff0c;关键的Boss和精英怪不会重复刷&#xff0c;同时场景里放一些资源可收集&#xff0c;基地建设锁定区…...

设置jmeter外观颜色

设置jmeter外观颜色 方法&#xff1a; 步骤一、点击顶部选项 ->外观&#xff0c;这里提供了不同的主题&#xff0c;可选自己喜欢的风格。 步骤二、选择后&#xff0c;弹框提示点击Yes。...

《一文读懂!Q-learning状态-动作值函数的直观理解》

在人工智能的强化学习领域&#xff0c;Q-learning算法是一颗耀眼的明星&#xff0c;被广泛应用于机器人控制、游戏AI开发、自动驾驶等诸多前沿领域。而想要真正掌握Q-learning算法&#xff0c;理解其核心概念——状态 - 动作值函数&#xff0c;是绕不开的关键一步。这篇文章就带…...

Angular 2 表单深度解析

Angular 2 表单深度解析 引言 Angular 2作为现代前端开发的框架之一,以其灵活性和强大的功能赢得了众多开发者的青睐。在Angular 2中,表单处理是其中一个重要且复杂的部分。本文将深入解析Angular 2的表单,从基础知识到高级应用,旨在帮助开发者更好地理解和运用Angular 2…...

使用kitty terminal遇到的‘xterm-kitty‘: unknown terminal type.

解决办法 方式一 export TERMxterm-256color使永久生效 echo export TERMxterm-256color >> ~/.zshrc # 如果用 zsh&#xff0c;如果使用的是bash就修改为bashrc source ~/.zshrc #同理如果是ssh下遇到该问题&#xff0c;参考 https://sw.kovidgoyal.net/kitty/faq/…...

Dest1ny漏洞库:用友 U8 Cloud ReleaseRepMngAction SQL 注入漏洞(CNVD-2024-33023)

大家好&#xff0c;今天是Dest1ny漏洞库的专题&#xff01;&#xff01; 会时不时发送新的漏洞资讯&#xff01;&#xff01; 大家多多关注&#xff0c;多多点赞&#xff01;&#xff01;&#xff01; 0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP&#xff0c;主要聚…...

代码随想录|动态规划 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

300.最长递增子序列 题目 参考文章 思路&#xff1a;dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度 因为没有连续&#xff0c;所以每一个元素都要比较&#xff0c;从而得到结果 两个递增子序列一定分别以nums[j]为结尾 和 nums[i]为结尾&#xff0c; 要不然这个比…...

Flutter_学习记录_导航和其他

Flutter 的导航页面跳转&#xff0c;是通过组件Navigator 和 组件MaterialPageRoute来实现的&#xff0c;Navigator提供了很多个方法&#xff0c;但是目前&#xff0c;我只记录我学习过程中接触到的方法&#xff1a; Navigator.push(), 跳转下一个页面Navigator.pop(), 返回上一…...

【信息系统项目管理师-选择真题】2006下半年综合知识答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第…...

面向对象编程简史

注&#xff1a;本文为 “面向对象编程简史” 相关文章合辑。 英文引文&#xff0c;机翻未校。 Brief history of Object-Oriented Programming 面向对象编程简史 Tue, May 14, 2024 Throughout its history, object-oriented programming (OOP) has undergone significant …...

快速提升网站收录:内容创作的艺术

本文来自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/15.html 快速提升网站收录&#xff0c;内容创作是关键。以下是一些关于内容创作以提升网站收录的艺术性建议&#xff1a; 一、关键词研究与优化 选择长尾关键词&#xff1a;进行深入的关键…...

高速PCB设计指南3——PCB 传输线和受控阻抗

高速PCB设计指南3——PCB 传输线和受控阻抗 1. 传输线1.1 传输线的定义1.2 传输线的分类1.3 互为传输线的情况 2. 均匀传输线的特性阻抗3. PCB中受控阻抗结构3.1 微带线&#xff08;Microstrip&#xff09;3.2 带状线&#xff08;Stripline&#xff09; 4 阻抗控制方法5. 阻抗控…...

python实现一个完整的智能教室能耗监测与管理系统的实现方案

以下是一个完整的智能教室能耗监测与管理系统的实现方案&#xff0c;主要使用Python语言&#xff0c;涵盖深度学习模型研发、教室场景适应性分析、系统架构设计、前端展示、后端服务以及测试评估等方面。 1. 数据准备 首先&#xff0c;需要收集教室的照片数据集&#xff0c;并…...

【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测

&#x1f525;【新春特辑】2025年春节技术展望&#xff1a;蛇年里的科技创新与趋势预测 &#x1f4c5; 发布日期&#xff1a;2025年01月29日&#xff08;大年初一&#xff09; 在这个辞旧迎新的美好时刻&#xff0c;我们迎来了充满希望的2025年&#xff0c;也是十二生肖中的蛇…...

woocommerce独立站与wordpress独立站的最大区别是什么

WooCommerce独立站与WordPress独立站的最大区别在于它们的功能定位和使用场景。 WordPress是一个开源的内容管理系统(CMS)&#xff0c;最初是作为博客平台发展起来的&#xff0c;但现在已经演变为一个功能丰富的网站构建工具。它主要用于创建动态网站&#xff0c;提供广泛的定…...

docker安装MySQL8:docker离线安装MySQL、docker在线安装MySQL、MySQL镜像下载、MySQL配置、MySQL命令

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull mysql:8.0.41 2、离线包下载 两种方式&#xff1a; 方式一&#xff1a; -&#xff09;在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -&#xff09;导出 # 导出镜…...

PTA乙级1006~1010【c++】

1006 换个格式输出整数 #include <iostream> using namespace std;int main(){int n;cin >> n;int b n / 100;int s n / 10 % 10;int g n % 10;for (int i 0; i < b; i ) cout << B;for (int i 0; i < s; i ) cout << S;for (int i 0; …...

一文掌握ADB的安装及使用

文章目录 一、什么是ADB&#xff1f;二、 安装ADB2.1 下载ADB2.2 配置环境变量 三、连接Android设备四、 常用ADB命令五、ADB高级功能5.1 屏幕截图和录制5.2 模拟按键输入5.3 文件管理5.4 系统设置管理5.5 系统操作指令5.6 日志操作指令5.7 APK操作指令5.8 设备重启和恢复 六、…...

ThinkPad E480安装Ubuntu 18.04无线网卡驱动

个人博客地址&#xff1a;ThinkPad E480安装Ubuntu 18.04无线网卡驱动 | 一张假钞的真实世界 遗憾的是虽然下面的方法可以解决&#xff0c;但是内核升级后需要重新安装。 基本信息 Ubuntu 18.04ThinkPad E480使用下面的命令查看 Linux 内核&#xff1a; $ uname -r 5.0.0-3…...

QT+mysql+python 效果:

# This Python file uses the following encoding: utf-8 import sysfrom PySide6.QtWidgets import QApplication, QWidget,QMessageBox from PySide6.QtGui import QStandardItemModel, QStandardItem # 导入需要的类# Important: # 你需要通过以下指令把 form.ui转为ui…...

关于 SR-IOV 架构论文的总结文章

关于 SR-IOV 架构论文的总结文章 在计算机虚拟化技术不断发展的进程中,SR - IOV 架构凭借其在提升 I/O 性能、优化资源利用等方面的优势,成为众多研究关注的焦点。通过对 4 篇相关论文的研读,我们可以从多个维度深入了解 SR - IOV 架构的核心要点。 一、SR - IOV 架构的原…...

MyBatis最佳实践:提升数据库交互效率的秘密武器

第一章&#xff1a;框架的概述&#xff1a; MyBatis 框架的概述&#xff1a; MyBatis 是一个优秀的基于 Java 的持久框架&#xff0c;内部对 JDBC 做了封装&#xff0c;使开发者只需要关注 SQL 语句&#xff0c;而不关注 JDBC 的代码&#xff0c;使开发变得更加的简单MyBatis 通…...

cursor ide配置远程ssh qt c++开发环境过程记录

cursor是啥就不介绍了&#xff0c;好像是目前最好用的ai ide&#xff0c;下面主要是配置远程ssh连接linux机器进行qt5 c程序运行的配置过程记录。 一、c_cpp_properties.json 在项目根目录的.vscode目录里面新建c_cpp_properties.json文件&#xff0c;根据你的实际情况配置该文…...

萌新学 Python 之数值处理函数 round 四舍五入、abs 绝对值、pow 幂次方、divmod 元组商和余数

关于数值处理的常用函数&#xff1a;round、abs、pow、divmod 1. round(数值[,小数位]) 四舍五入 说明&#xff1a;对数值进行四舍五入&#xff0c;小数位可以没有&#xff0c;也可以是负数&#xff08;从小数点左边开始进行&#xff09; round(数值[,小数位]) 四舍五入 #…...

vim交换文件的作用

1.数据恢复&#xff1a;因为vim异常的退出&#xff0c;使用交换文件可以恢复之前的修改内容。 2.防止多人同时编辑&#xff1a;vim检测到交换文件的存在,会给出提示&#xff0c;以避免一个文件同时被多人编辑。 &#xff08;vim交换文件的工作原理&#xff1a;vim交换文件的工作…...

NoSQL与SQL比较

1.认识NoSQL NoSql可以翻译做Not Only Sql&#xff08;不仅仅是SQL&#xff09;&#xff0c;或者是No Sql&#xff08;非Sql的&#xff09;数据库。是相对于传统关系型数据库而言&#xff0c;有很大差异的一种特殊的数据库&#xff0c;因此也称之为非关系型数据库。 1.1.结构…...

ThinkPHP 8模型与数据的插入、更新、删除

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…...