LLM之RAG实战(五十二)| 如何使用混合搜索优化RAG 检索
在RAG项目中,大模型生成的参考内容(专业术语称为块)来自前一步的检索,检索的内容在很大程度上直接决定了生成的效果,因此检索对于RAG项目至关重要,最常用的检索方法是关键字搜索和语义搜索。本文将分别介绍这两种搜索策略,然后将它们结合起来进行混合检索。
一、使用 BM25 进行关键字搜索
BM25 是关键字搜索的首选算法。使用 BM25,我们可以为语料库中每个文档的查询获得分数。
BM25 基于 TF-IDF 算法,这意味着公式的核心是术语频率 (TF) 和逆向文档频率 (IDF) 的乘积。
TF-IDF 算法基于以下理念:“对频率较低、更具体的术语的匹配比对频繁术语的匹配更有价值”
换句话说,TF-IDF 算法会查找包含查询中罕见关键字的文档。
如果我们看一下 LangChain 源码(https://api.python.langchain.com/en/latest/_modules/langchain_community/retrievers/bm25.html#BM25Retriever),可以看到它使用了 rank_bm25 包中的 BM25Okapi 类,该类是 ATIRE BM25 算法的略微修改版本。
在 ATIRE BM25 版本中,获得文档 d 和由多个词 t 组成的给定查询 q的分数的公式如下
-
N 是语料库中的文档数
-
df_t 是包含术语 t 的文档数 (也称为文档频率)
-
tf_td 是术语 t 在文档 d 中出现的次数(也称为术语频率)
-
L_d是我们文档的长度,L_avg是平均文档长度
-
有两个经验调优参数: b 和 k_1
我们看到公式对所有项 t 求和,我们可以将其视为单词。
BM25 方程中的左手因子 log(N/df_t) 称为逆文档频率。对于像 “the” 这样的常用词,我们所有的文档都可能包含,所以逆向文档频率将为零(因为 log(1) 为零)。
另一方面,非常罕见的单词只会出现在少数文档中,从而增加左因子。因此,逆向文档频率是衡量术语 t 中包含多少信息的量度。
右因子受术语 t 在文档 d 中出现的次数的影响。
该文档 d=["I like red cats, black cats, white cats, and brown cats"] 对词 t=“cats” 具有非常高的词频tf_td,这将导致包含单词 “cats” 的查询获得较高的 BM25 分数。
让我们使用 BM25 来使用 Python 库rank_bm25来获得一些直觉。
pip install rank_bm25
首先,我们加载库并使用我们的标记化语料库初始化 BM25。
from rank_bm25 import BM25Okapi
corpus = [
"The cat, commonly referred to as the domestic cat or house cat, is a small domesticated carnivorous mammal.",
"The dog is a domesticated descendant of the wolf.",
"Humans are the most common and widespread species of primate, and the last surviving species of the genus Homo.",
"The scientific name Felis catus was proposed by Carl Linnaeus in 1758"]
tokenized_corpus = [doc.split(" ") for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)
接下来,我们对查询进行标记化。
query = "The cat"
tokenized_query = query.split(" ")
最后,我们使用 BM25 算法计算分数。高分表示文档和查询之间的匹配良好。
doc_scores = bm25.get_scores(tokenized_query)
print(doc_scores) >> [0.92932018 0.21121974 0. 0.1901173]# scores for documents 1, 2, 3, and 4
由于 BM25 查找完全匹配的术语,因此查询术语“cats”、“Cat”或“feline”都将导致三个示例文档的分数为 doc_scores = [0,0,0]。
二、使用密集嵌入的语义搜索
当我们通过密集嵌入执行语义搜索时,我们会将单词转换为数字表示。其理念是,在这种新的数学表示形式中,相似的单词紧密相连。
文本嵌入是单个单词或整个句子的高维向量。它们称为 dense,因为向量中的每个条目都是一个有意义的数字。相反,当许多 vector 条目只是为零时,称为 sparse。
在将单词转换为嵌入之前,首先通过称为编码器的神经网络嵌入模型将token转换为嵌入向量。
在将文档语料库中的所有文本转换为嵌入后,可以执行语义搜索以查看哪个嵌入文档最接近我们的嵌入查询。
我们可以通过绘制嵌入维度并找到与我们的查询最匹配的文档来可视化此任务。
在数学上,我们使用余弦距离函数找到最接近的匹配项。对于两个嵌入向量 a 和 b,我们可以使用点积计算余弦相似度,如下所示:
其中分子是两个嵌入向量的点积,分母是它们量级的乘积。
在几何学上,余弦相似度是向量之间的角度。余弦相似性分数范围为 -1 到 +1。
余弦相似度分数 -1 表示嵌入 a 和 b 正好朝向相反的方向,0 表示它们的角度为 90 度(它们无关),+1 表示它们相同。 因此,在将搜索查询与文档匹配时,我们会寻找接近 +1 的值。
如果我们事先对嵌入进行归一化,则余弦相似度测度将等效于点积相似度测度(分母变为 1)。
下面让我们使用 Python 包 sentence-transformers 来计算一下基本的语义搜索。
pip install sentence-transformers
首先,从 HuggingFace 下载全 MiniLM-L6-v2 编码器模型,可生成 384 维密集嵌入。
from sentence_transformers import SentenceTransformer
# 1. Load a pretrained Sentence Transformer model
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
然后,我们使用与以前相同的文档语料库。
# The documents to encode
corpus = [
"The cat, commonly referred to as the domestic cat or house cat, is a small domesticated carnivorous mammal.",
"The dog is a domesticated descendant of the wolf.",
"Humans are the most common and widespread species of primate, and the last surviving species of the genus Homo.",
"The scientific name Felis catus was proposed by Carl Linnaeus in 1758"]
# Calculate embeddings by calling model.encode()
document_embeddings = model.encode(corpus)
# Sanity check
print(document_embeddings.shape)
>> (4, 384)
对查询进行嵌入:
query = "The cat"
query_embedding = model.encode(query)
最后,计算余弦相似度分数。可以使用 sentence_transformers 中的 utility 函数 cos_sim,而不是自己编写公式。
from sentence_transformers.util import cos_sim
# Compute cosine_similarity between documents and query
scores = cos_sim(document_embeddings, query_embedding)
print(scores)
>> tensor([[0.5716], # score for document 1
>> [0.2904], # score for document 2
>> [0.0942], # score for document 3
>> [0.3157]]) # score for document 4
为了了解使用密集嵌入的语义搜索的强大功能,我可以使用查询 “feline” 重新运行代码:
query_embedding = model.encode("feline")
scores = cos_sim(document_embeddings, query_embedding)
print(scores)
>> tensor([[0.4007],
>> [0.3837],
>> [0.0966],
>> [0.3804]])
即使 “feline” 一词没有出现在文档语料库中,语义搜索仍然将有关猫的文本列为最高匹配度。
三、语义搜索还是关键字搜索?
哪种搜索方法更好?这要看情况。两者都有优点和缺点。现在我们知道了两者的工作原理,我们可以看到它们在哪些方面有用,哪些方面可能失败。
使用 BM25 进行关键字搜索会查找查询词的完全匹配项。当我们在寻找短语的精确匹配时,这可能非常有用。
如果我在找《帽子里的猫》(The Cat in the Hat),我可能在找这本书/电影。而且我不希望出现语义上相似的结果,这些结果接近 hats 或 cats。
关键字搜索的另一个用例是编程。如果我正在寻找特定的函数或代码段,我想要一个完全匹配。
另一方面,语义搜索会查找语义相似的内容。这意味着语义搜索还会查找具有同义词或不同拼写(如复数、大写等)的文档。
由于这两种算法都有其用例,因此混合搜索同时使用这两种算法,然后将它们的结果合并为一个最终排名。
混合搜索的缺点是它比只运行一种算法需要更多的计算资源。
四、混合搜索
我们可以使用倒数秩融合 (RRF) 将 BM25 和余弦相似性的结果结合起来。RRF 是一种简单的算法,用于组合不同评分函数的排名 [4]。
首先,我们需要获取每种评分算法的文档排名。在我们的示例中,这将是:
corpus = [
"The cat, commonly referred to as the domestic cat or house cat, is a small domesticated carnivorous mammal.",
"The dog is a domesticated descendant of the wolf.",
"Humans are the most common and widespread species of primate, and the last surviving species of the genus Homo.",
"The scientific name Felis catus was proposed by Carl Linnaeus in 1758",]
query = "The cat"
bm25_ranking = [1, 2, 4, 3] # scores = [0.92932018 0.21121974 0. 0.1901173]
cosine_ranking = [1, 3, 4, 2] # scores = [0.5716, 0.2904, 0.0942, 0.3157]
每个文档 d 的综合 RRF 分数公式如下:
其中 k 是一个参数(原始论文使用 k=60),r(d) 是 BM25 和余弦相似度的排名。
现在,我们可以通过分别进行 BM25 和余弦相似性,然后将结果与 RRF 相结合来实现我们的混合搜索。
首先,让我们定义 RRF 的函数和将浮点分数转换为 int 排名的辅助函数。
import numpy as np
def scores_to_ranking(scores: list[float]) -> list[int]:
"""Convert float scores into int rankings (rank 1 is the best)"""
return np.argsort(scores)[::-1] + 1
def rrf(keyword_rank: int, semantic_rank: int) -> float:
"""Combine keyword rank and semantic rank into a hybrid score."""
k = 60
rrf_score = 1 / (k + keyword_rank) + 1 / (k + semantic_rank)
return rrf_score
这是我使用上述概念的简单混合搜索实现。
from rank_bm25 import BM25Okapi
from sentence_transformers import SentenceTransformer
from sentence_transformers.util import cos_sim
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
def hybrid_search(
query: str, corpus: list[str], encoder_model: SentenceTransformer
) -> list[int]:
# bm25
tokenized_corpus = [doc.split(" ") for doc in corpus]
tokenized_query = query.split(" ")
bm25 = BM25Okapi(tokenized_corpus)
bm25_scores = bm25.get_scores(tokenized_query)
bm25_ranking = scores_to_ranking(bm25_scores)
# embeddings
document_embeddings = model.encode(corpus)
query_embedding = model.encode(query)
cos_sim_scores = cos_sim(document_embeddings, query_embedding).flatten().tolist()
cos_sim_ranking = scores_to_ranking(cos_sim_scores)
# combine rankings into RRF scores
hybrid_scores = []
for i, doc in enumerate(corpus):
document_ranking = rrf(bm25_ranking[i], cos_sim_ranking[i])
print(f"Document {i} has the rrf score {document_ranking}")
hybrid_scores.append(document_ranking)
# convert RRF scores into final rankings
hybrid_ranking = scores_to_ranking(hybrid_scores)
return hybrid_ranking
现在我们可以将 hybrid_search 用于不同的查询。
hybrid_ranking = hybrid_search(
query="What is the scientifc name for cats?", corpus=corpus, encoder_model=model
)
print(hybrid_ranking)
>> Document 0 has the rrf score 0.03125
>> Document 1 has the rrf score 0.032266458495966696
>> Document 2 has the rrf score 0.03225806451612903
>> Document 3 has the rrf score 0.032266458495966696
>> [4 2 3 1]
相关文章:
LLM之RAG实战(五十二)| 如何使用混合搜索优化RAG 检索
在RAG项目中,大模型生成的参考内容(专业术语称为块)来自前一步的检索,检索的内容在很大程度上直接决定了生成的效果,因此检索对于RAG项目至关重要,最常用的检索方法是关键字搜索和语义搜索。本文将分别介绍…...
如何基于ios部署Deep Seek?
在 iOS 上部署深度学习模型(如 DeepSeek 或其他自定义模型)通常需要将模型转换为 iOS 支持的格式(如 Core ML),并通过代码集成到应用中。以下是详细步骤: 1. 准备模型 模型训练 确保你的模型已训练完成&…...
spring security 使用的过滤器还是拦截器
spring security 使用的过滤器还是拦截器 Spring Security 是一个强大的安全框架,用于保护 Java 应用程序。它主要使用过滤器(Filters)来实现安全功能,而不是拦截器(Interceptors)。不过,它也提…...
新四化驱动,如何构建智能汽车的“全场景”可进化互联网络?
在智能化、电动化、网联化、共享化的时代浪潮中,汽车正从单纯的 “机械产品” 进化为先进的 “移动智能终端”。 在软件定义汽车(SDV)的崭新时代,每一次 OTA 升级的顺利完成、每一秒自动驾驶的精准决策、每一帧车载娱乐交互的流畅…...
Rust从入门到精通之进阶篇:17.宏编程基础
宏编程基础 宏是 Rust 中强大的元编程工具,允许你编写可以生成其他代码的代码。与函数不同,宏在编译时展开,可以实现更灵活的代码生成和重用模式。在本章中,我们将探索 Rust 的宏系统,包括声明宏和过程宏的基础知识。 宏与函数的区别 在深入宏编程之前,让我们先了解宏…...
MySQL基础语法
目录 一、数据定义语言(DDL) 1. 创建数据库 2. 删除数据库 3. 创建表 4. 删除表 5. 查看表结构 6. 修改表结构 二、数据操作语言(DML) 1. 插入数据 2. 更新数据 3. 删除数据 三、数据查询语言(DQLÿ…...
数据结构练习二习题
第七题: #include<bits/stdc.h> using namespace std;#define MaxSize 100 // 定义顺序表的最大长度typedef int ElemType; // 定义元素类型为inttypedef struct {ElemType data[MaxSize]; // 存储数据的数组int length; // 当前顺序表的长度…...
Flutter 中 GetX 的优缺点及常见问题解决方案
在 Flutter 生态中,GetX 凭借其轻量级、高效的特性,成为众多开发者青睐的状态管理与路由解决方案。然而,任何工具都有其适用场景与局限性。 一、GetX 的核心优势 1. 极简开发体验 GetX 通过响应式语法糖(如Rx和Obx)…...
Qt开发:QColorDialog的使用
文章目录 一、QColorDialog的基本介绍二、QColorDialog的基本用法三、完整示例 一、QColorDialog的基本介绍 QColorDialog 继承自 QDialog,用于让用户选择颜色。它可以以模态或非模态的方式运行,并支持 QColor 作为输入和输出。 二、QColorDialog的基本…...
【计算机网络编码与调制】
文章目录 一、前言二、编码与调制的基本概念1. 编码常见编码类型: 2. 调制常见调制类型: 三、常见编码技术1. NRZ编码(Non-Return to Zero)特点: 2. 曼彻斯特编码(Manchester)特点: …...
<数据集>手势识别数据集<目标检测>
数据集下载链接https://download.csdn.net/download/qq_53332949/90529961数据集格式:VOCYOLO格式 图片数量:10829张 标注数量(xml文件个数):10829 标注数量(txt文件个数):10829 标注类别数:26 标注类别名称&…...
魔法测试:用本地多模态大模型(Qwen2.5-VL)将PDF转为Markdown文档
安装咒语清单 📜 pip install -U vllm qwen-vl-utils pdf2image pip install githttps://github.com/huggingface/transformers accelerate(温馨提示:念咒前请检查你的魔法棒(Python环境)是否兼容~) 第一阶段:PDF变…...
【渗透测试】Fastjson 反序列化漏洞原理(二)
目录 反序列化漏洞结合 RMI 攻击详解一、RMI 和 JNDI 的基础知识(1) RMI 简介(2) JNDI 简介 二、漏洞利用的核心原理1. 构造恶意 JSON 数据2. 设置恶意 RMI 服务3. 加载并执行恶意代码 三、具体利用过程环境准备攻击步骤1. 构造恶意 JSON 数据2. 设置恶意 RMI 服务3. 部署恶意类…...
[c语言日寄MAX]深度解析:大小端字节序
【作者主页】siy2333 【专栏介绍】⌈c语言日寄MAX⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还…...
凝视型高光谱相机:钻石光谱分析研究与应用
钻石作为一种珍贵的宝石,其颜色和光谱特征一直是宝石学研究的重要方向。中达瑞和测试部样品科对六种不同颜色的钻石样品进行了高光谱成像测试,旨在分析它们在光谱下的差异和可分性。本文将详细介绍此次测试的过程、结果及其意义。 测试样品与设备 此次…...
2.基于多线程的TCP服务器实现
在我们预想中,服务器端应该能够同时与多个客户端建立连接并进行网络通信。然而,在之前的代码中,服务器实现只支持单一连接,因为在处理连接时,主线程会被accept()、read()或write()等方法阻塞,导致无法响应新…...
自动驾驶01 激光雷达原理
部分转载于 原文链接:https://blog.csdn.net/qq_45193988/article/details/143982588 1. 什么是激光雷达 激光雷达LiDAR的全称为Light Detection and Ranging 激光探测和测距。 激光雷达的工作原理:对红外光束Light Pluses发射、反射和接收来探测物体。…...
基础场景-------------------(5)重载和重写的区别
重写(Override) 从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继 承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列 表,返回…...
基于ssm的微博网站(全套)
进入信息时代以来,很多数据都需要配套软件协助处理,这样可以解决传统方式带来的管理困扰。比如耗时长,成本高,维护数据困难,数据易丢失等缺点。本次使用数据库工具MySQL和编程技术JSP开发的微博网站,可以实…...
Java并发编程从入门到实战:同步、异步、多线程核心原理全解析
《Java并发编程从入门到实战:同步、异步、多线程核心原理全解析》 一、多线程基础认知(从单核到多核的进化) 1.1 什么是线程? 线程是程序执行的最小单元,一个进程可以包含多个线程。例如浏览器同时下载文件࿰…...
《引流获客》总结
第一章 入门篇 理解爆款打法和引流打法的区别 爆款打法:刷播放量,制作“爆款”视频/文案。 引流打法:刷有效转化,不在意播放量,而注重有多少观众被引流成为客户,完成消费,即成交转化。 定理&…...
基于Python的机器学习入门指南
在当今数字化时代,机器学习(Machine Learning)已经成为科技领域中最热门的话题之一。它不仅改变了我们对数据的理解和处理方式,还在许多行业中得到了广泛应用,如金融、医疗、交通等。Python作为一门强大的编程语言&…...
【蓝桥杯每日一题】3.25
🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x “OJ超时不是终点,是算法在提醒你该优化时间复杂度了!” 目录 3.25 差分数组 一、一维差分 题目链接: 题目描述: 解题思路:…...
Kubernetes高级应用之-重启策略
一、介绍+扩展应用(涉及的高级资源在后续会写出来) # Kubernetes Pod重启策略(RestartPolicy)全面解析 ## 一、重启策略的核心价值与重要性 在Kubernetes集群中,Pod重启策略(RestartPolicy&a…...
Axure RP9.0教程: 多级联动【设置选项改变时->情形->面板状态】(给动态面板元件设置相关交互事件的情形,来控制其他面板不同的状态。)
文章目录 引言I 多级联动(省、市、区)实现思路添加三省、市、区下拉列表给省下拉框添加数据源将市、区下拉框添加不同状态,分别以省、市命名给省下拉控件设置选项改变时的交互事件省下拉控件的交互事件情形市下拉交互事件的配置II 知识扩展: 展示省 → 地级市 → 区县的多级…...
Next.js 严重漏洞:攻击者可绕过中间件授权检查
Next.js React 框架近日披露了一个严重的安全漏洞,攻击者可在特定条件下利用该漏洞绕过授权检查。该漏洞被标记为 CVE-2025-29927,其 CVSS 评分为 9.1(满分 10.0)。 漏洞详情 Next.js 在公告中表示:“Next.js 使用内…...
气象可视化卫星云图的方式:方法与架构详解
气象卫星云图是气象预报和气候研究的重要数据来源。通过可视化技术,我们可以将卫星云图数据转化为直观的图像或动画,帮助用户更好地理解气象变化。本文将详细介绍卫星云图可视化的方法、架构和代码实现。 一、卫星云图可视化方法 1. 数据获取与预处理 卫星云图数据通常来源…...
NLP高频面试题(十四)——DPO、PPO等强化学习训练方法介绍
强化学习(Reinforcement Learning,RL)近年来随着深度学习的快速发展而备受关注,特别是在游戏控制、自动驾驶、机器人控制及大语言模型训练等领域均有广泛应用。本文将重点介绍强化学习中的经典训练方法,包括PPO&#x…...
从 Neo4j 数据库中提取数据并绘制图谱
代码说明: 连接 Neo4j 数据库: 使用 py2neo.Graph 连接到 Neo4j 数据库。确保替换 uri、username 和 password 为你的实际配置。 Cypher 查询: 查询数据库中的节点和关系,限制返回的记录数(例如 LIMIT 100)…...
Android Compose 框架隐式动画之过渡动画深入剖析(二十六)
Android Compose 框架隐式动画之过渡动画深入剖析 一、引言 在移动应用开发领域,用户体验始终是至关重要的。动画效果作为提升用户体验的关键元素,能够为应用增添生动性和交互性。Android Compose 作为现代 Android UI 工具包,为开发者提供…...
esp32s3聊天机器人(三)
先放上最新的硬件图 添加了按钮、600毫安锂电池和充电板 关于 sherpa-onnx 语音生成的打断 按说明实现了一下,但是偶尔还是有问题,毕竟不是直接立刻打断生成 private int OnAudioData(nint samples, int n){//Console.WriteLine("OnAudioData n…...
超融合服务器是什么
超融合服务器的定义与背景 超融合服务器(Hyperconverged Infrastructure, HCI)是一种通过软件定义技术,将计算、存储、网络和虚拟化功能整合到单一硬件平台中的IT基础设施解决方案。其核心目标是通过资源的高度集成和统一管理,简…...
Rust从入门到精通之精通篇:22.Unsafe Rust 详解
Unsafe Rust 详解 在 Rust 的设计哲学中,安全性是核心原则之一。Rust 的所有权系统、借用检查器和类型系统共同保证了内存安全和线程安全。然而,有些底层操作无法通过 Rust 的安全检查机制进行验证,这就是 unsafe Rust 存在的原因。在本章中,我们将深入探讨 unsafe Rust,…...
如何设计系统扩展性以应对业务增长
要设计具备良好扩展性的系统以应对业务增长,关键在于采用分布式架构、实现服务的松耦合、保证数据库的水平扩展能力、使用缓存和CDN优化性能、做好持续监控与自动化运维。其中,服务的松耦合尤为重要。松耦合意味着系统中各服务之间的依赖关系较弱&#x…...
Python基于Django的小区监控图像拼接系统【附源码、文档说明】
博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...
ElasticSearch快速入门--实现分词搜索
分词题目搜索 使用Elasticsearch实现题目数据的存储和分词搜索,需要将数据库的数据同步到 Elasticsearch。 ElasticSearch入门 ElasticSearch(简称ES)是一个开源的分布式搜索和数据分析引擎,用Java开发并且是当前最流行的开源的…...
解读探寻数字影像新路径:树莓集团现状最新进展
树莓集团在数字影像领域展现出强劲的发展势头,其核心战略在于构建完整的数字产业生态链。 产业园建设与运营 全国布局: 树莓集团已在全国范围内建设并运营多个国际数字影像产业园,旨在打造区域性的数字产业高地。 成都案例: 在成…...
数据治理之数据仓库
本文主要阐述了数据仓库在大数据平台项目中的地位和重要性,对目前市场上数据仓库主流设计进行分析说明,讲述了通用数据仓库设计上所应考虑的因素。 数据仓库介绍 数据仓库是一个过程而不是一个项目;数据仓库是一个环境,而不是一件产品。数据仓库提供用户用于决策支持的当前…...
自由学习记录(48)
When the material of an object disappears, the light and shadow also disappear (synchronized) Tiling And Offset 显示的是四分之一前面的,不是中间的四分之一块, 准确的还是跟着视频学, ,AI一些回答会散发一种“奇怪的错味…...
zynq7020 最小ps环境速通
1 简介 环境: 硬件 野火 zynq 皓月 xc7z020clg400-1 软件: vivado2020.2 vitis2020.2 petalinux2020.2 搭建 ps 的最小环境,跑裸机 helloworld 测试 uart 和 ddr,跑 linux 系统. 2 ps 环境搭建 2.1 uart 2.1 ddr 2.1 删除 pl 接口,包括 pl 时钟,pl 时钟复位,axi_m. 具体略…...
Modbus RTU ---> Modbus TCP透传技术实现(Modbus透传、RS485透传、RTU透传)分站代码实现
文章目录 Modbus RTU到Modbus TCP透传技术实现1. 透传技术概述1.1 透传基本原理- 协议帧格式转换- 地址映射与管理- 通信时序适配- 错误检测与处理 2. 透传网关硬件架构2.1 典型硬件结构- 微控制器/处理器(ARM、STM32等)- RS-485/RS-232收发器- 以太网控制器(如W5500)- 电源管理…...
【SOC 芯片设计 DFT 学习专栏 -- IDDQ 测试 与 Burn-In 测试】
文章目录 IDDQ 测试与 Burn-In 测试IDDQ 测试工作原理测试过程优点局限性示例 2. Burn-In 测试工作原理测试过程优点局限性示例 总结对比 IDDQ 测试和 Burn-in 测试: IDDQ 测试与 Burn-In 测试 本文将详细介绍 DFT 中 IDDQ测试 和 burn-in测试模式 IDDQ 测试 IDD…...
Rust从入门到精通之进阶篇:19.Rust 生态系统
Rust 生态系统 Rust 拥有一个丰富而活跃的生态系统,提供了各种库和框架来支持不同领域的开发。在本章中,我们将探索 Rust 生态系统中的主要组件,了解常用的库和工具,以及如何在项目中有效地使用它们。 Rust 包管理:Cargo 和 crates.io Cargo 回顾 Cargo 是 Rust 的构建…...
【HarmonyOS Next】三天撸一个BLE调试精灵
【HarmonyOS Next】三天撸一个BLE调试精灵 一、功能介绍 BLE调试精灵APP属于工具类APP,在用户使用的过程中,负责调试BLE设备从机端,比如蓝牙耳机、低功耗设备、带有BLE的空调等设备,可以在页面中清晰看到设备的厂商,…...
STM32实现智能温控系统(暖手宝):PID 算法 + DS18B20+OLED 显示,[学习 PID 优质项目]
一、项目概述 本文基于 STM32F103C8T6 单片机,设计了一个高精度温度控制系统。通过 DS18B20 采集温度,采用位置型 PID 算法控制 PWM 输出驱动 MOS 管加热Pi膜,配合 OLED 实时显示温度数据。系统可稳定将 PI 膜加热至 40℃,适用于…...
【docker】docker-compose安装RabbitMQ
docker-compose安装RabbitMQ 1、配置docker-compose.yml文件(docker容器里面的目录请勿修改)2、启动mq3、访问mq4、查看服务器映射目录5、踩坑5.1、权限不足 1、配置docker-compose.yml文件(docker容器里面的目录请勿修改) versi…...
如何突破MacBook苹果电脑Cursor限制:免费版的解决方法
Macbook苹果电脑无限白嫖Cursor|解决免费版限制问题|达到50次150次续杯|arm|intel 如何突破MacBook苹果电脑Cursor限制:免费版的解决方法 前言 本文介绍了如何在MacBook上突破Cursor免费版的使用限制。请遵循以下步骤进行操作。 操作步骤 进入程序目录:…...
网络原理之传输层
前文我们了解 应用层 传输层 网络层 数据链路层 物理层 这五层结构,此文我先讨论传输层相关的知识 1. 传输层 负责数据能够从发送端传输到接收端. 1.1 端口号 端⼝号(Port)标识了⼀个主机上进行通信的不同的应用程序 端口号范围划分: 0-1023:知名端口号,HTTP,FTP,SSH等这些…...
一个免费 好用的pdf在线处理工具
pdf24 doc2x 相比上面能更好的支持数学公式。但是收费...
新书速览|云原生Kubernetes自动化运维实践
《云原生Kubernetes自动化运维实践》 本书内容: 《云原生Kubernetes自动化运维实践》以一名大型企业集群运维工程师的实战经验为基础,全面系统地阐述Kubernetes(K8s)在自动化运维领域的技术应用。《云原生Kubernetes自动化运维实践…...