在android 系统上qnn sdk转换,运行模型示例
前面讲了如何配置qnn sdk的环境,这一篇总结下qnn 实际转换一个onnx 模型,并运行的实现步骤。
设备:
1. ubuntu22.04 的Linux 服务器。
2. 一台android手机。
一、下载模型
from optimum.onnxruntime import ORTModelForSequenceClassification
from transformers import AutoTokenizerdef download_model():model_path = "BAAI/bge-base-zh-v1.5"save_directory = "./bge-base-zh-v1.5.onnx"# 从 Transformers 加载模型并将其导出为 ONNXmodel = ORTModelForSequenceClassification.from_pretrained(model_path, export=True)tokenizer = AutoTokenizer.from_pretrained(model_path)# 保存 ONNX 模型和分词器model.save_pretrained(save_directory)tokenizer.save_pretrained(save_directory)
Check模型和简化模型,固定shape.方便后续的处理。
onnxsim ./bge-model.onnx bge-simple2-model.onnx --overwrite-input-shape inputs_ids:1,512 --overwrite-input-shape attention_mask:1,512 --overwrite-input-shape token_type_ ids:1,512
二、构建量化数据
因为真实数据集对于构建量化是非常重要的,量化的质量直接影响到模型的推理结果准确性,使用的校准数据应该最大程度上接近训练和测试的数据集,这样子测试的效果更加的贴合实际业务场景的测试结果。
Embedding模型的主要测试数据集通常包括多种语言和任务类型的数据集,以全面评估模型的性能。例如,MTEB(Massive Text Embedding Benchmark)是一个大规模的文本嵌入基准测试,旨在全面评估文本嵌入方法的性能。MTEB 覆盖了 8 种嵌入任务,包含 58 个数据集和 112 种语言。此外,C-MTEB 是专门针对中文文本向量的评测基准,共收集了35个公共数据集,分为6类的评估任务。这些数据集可以帮助评估Embedding模型在不同语言和任务上的表现。所以我们选择C-MTEB(Chinese Massive Text Embedding Benchmark)测试中使用的LCQMC数据集进行构建量化需要的校准数据。
-
使用python 加载C-MTEB/LCQMC数据集。
-
使用tokener进行文本的词化。
-
将数据保存成三个输入,格式是raw,也就是原始的二进制文件。
def create_lcqmc_quant_data():dataset = load_dataset("C-MTEB/LCQMC", split="test")sentence = dataset["sentence1"]model = AutoModel.from_pretrained("BAAI/bge-base-zh-v1.5")tokenizer = AutoTokenizer.from_pretrained("./")#开启评估模式model.eval()calib_data_size = 100input_data = tokenizer(sentence, padding="max_length", truncation=True, max_length=512, return_tensors="pt")input_ids = input_data["input_ids"].numpy().astype(np.int32)[:calib_data_size, :]attention_mask = input_data["attention_mask"].numpy().astype(np.int32)[:calib_data_size, :]token_type_ids = input_data["token_type_ids"].numpy().astype(np.int32)[:calib_data_size, :]calib_data_dir = "calib_data"os.makedirs(calib_data_dir)path_lists = []path_file = "input_list.txt"# one for funcation to iter multi arrfor index, (arr, name) in enumerate(zip([input_ids, attention_mask, token_type_ids], ["input_ids", "attention_mask", "token_type_ids"])):# iter rows.# iter input_id, then mask, last token_idfor i in range(arr.shape[0]):# one arr save in one file.file_path = os.path.join(calib_data_dir, f"{name}_{i}.raw")#sava path.path_lists.append(file_path)## save data.arr[i].tofile(file_path)with open(path_file, "w", encoding="utf-8") as f:len = input_ids.shape[0]print(3*input_ids.shape[0])for i in range(input_ids.shape[0]):# one raw contain three input data file path.f.write(f"{os.path.abspath(path_lists[i])} {os.path.abspath(path_lists[i + len])} {os.path.abspath(path_lists[i + 2*len])}\n")print("create quant data finish.")
三、构建模型的运行输入数据
def create_model_input_data():model = AutoModel.from_pretrained("BAAI/bge-base-zh-v1.5")tokenizers = AutoTokenizer.from_pretrained("BAAI/bge-base-zh-v1.5")input_data = "ZhongGuo, nihao, 日本再见, good cat!"model.eval()current_path = os.path.abspath(__file__)dir_name = os.path.dirname(current_path)print(dir_name)real_data = "real_data"os.makedirs(real_data)input_ids_path = os.path.join(dir_name, "real_data" + "\\" + "input_ids.raw")attention_mask_path = os.path.join(dir_name, "real_data" + "\\" + "attention_mask.raw")token_type_ids_path = os.path.join(dir_name, "real_data" + "\\" + "token_type_ids.raw")## get inputinput_tensor_data = tokenizers(input_data, padding="max_length", truncation=True, max_length=512, return_tensors="pt" )input_tensor_data["input_ids"].numpy().astype(np.int32).tofile(input_ids_path)input_tensor_data["attention_mask"].numpy().astype(np.int32).tofile(attention_mask_path)input_tensor_data["token_type_ids"].numpy().astype(np.int32).tofile(token_type_ids_path)print(input_ids_path)path_list = [input_ids_path + " ", attention_mask_path + " ", token_type_ids_path + " "]with open("./input_data.txt", "w", encoding="utf-8") as f:f.writelines(path_list)
四、运行onnx 模型得到基准数据
def run_bge_model():model = AutoModel.from_pretrained("BAAI/bge-base-zh-v1.5")tokenizers = AutoTokenizer.from_pretrained("BAAI/bge-base-zh-v1.5")input_data = "ZhongGuo, nihao, 日本再见, good cat!"device = "cuda" if torch.cuda.is_available() else "cpu"model.to(device)model.eval()input_tensor_data = tokenizers(input_data, padding="max_length", truncation=True, max_length=512, return_tensors="pt" ).to(device)with torch.no_grad():output = model(**input_tensor_data)output_data = output.last_hidden_state.flatten().tolist()[:100]print(len(output.last_hidden_state.flatten().tolist()))print(output_data)
五、转换onnx 模型得到模型文件和权重数据。
python /home/shengqing.liu/qaisw-v2.12.0.230626174329_59328-auto/bin/x86_64-linux-clang/qnn-onnx-converter -o ./bge_real_data_qnn.cpp -i ./bge-simple-model.onnx --input_list ./input_list_calib.txt
转换成得到了三个文件bge_real_data_qnn.bin, bge_real_data_qnn.cpp, bge_real_data_qnn_net.json. 这三个文件就是qnn的模型文件。
.bin文件: 这个保存了qnn模型的参数。
.cpp文件:这个文件描述了qnn 模型结构的api 文件,依据这个文件可以创建qnn的计算图,Tool utility api 是用于生成 QNN API 调用的辅助模块。这些 API 是core QNN API 之上的轻量级包装器,旨在减少创建 QNN 图的重复步骤。
.json 文件:这个json 文件也是描述了qnn的模型结构文件,只是用来辅助描述模型结构文件的,这个文件后续的步骤中不会再使用到。
注意:
1. 将量化数据文件的绝对路径写入到input_list.txt中,相对路径是不行的,到时模型转换的时候会报错。
2. 加入--input_list 会使用默认的量化W8A8 进行量化模型,参看官方文档,查看支持的量化方法是min/max, 精度其实很差,基于经验,qnn的量化基本不可使用,勉强能用的W8A16 还要看特定的业务,一般也是精度达不到要求的。w16A16的量化需要芯片架构大于V73的才支持。
3. 设置其他的量化精度使用参数比如W8A16 --act_bw 16 --weight_bw 8
4. 实际中使用的都是半精度FP16 , 在转换的时候去除--input_list 参数,加上--float_bw 16 就是半精度模型了。类似这种
python ${QNN_SDK_ROOT_27}/bin/x86_64-linux-clang/qnn-onnx-converter -o ./bge_qnn_27_fp16_noquant.cpp -i ./bge-simple-model.onnx --float_bw 16
5. 半精度模型运行时候,加上--use_native_input_files , 精度会好很多,实际中需要加上这个参数。
六、得到动态库的so模型文件
将cpp 和bin 文件作为输入文件,使用qnn-model-lib-generator转换成so 库文件。得到了Android和linux 平台的so 文件,这个文件其实是动态加载模型文件,这个so 也可以进行运行,但是初始化的时间需要较长,当进一步转换成bin文件,进行编译优化的时候,推理运行时加载准备时间就大大减少。
${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-model-lib-generator -c ./bge_real_data_qnn.cpp -b ./bge_real_data_qnn.bin -o rag_qnn_so
得到so 模型文件,这两个目录下的so 都是可以直接运行的qnn 模型文件,android 目录下的是可以直接在android 系统运行的,linux 下的是在linux 平台运行的,并且在转bin 文件的时候,在linux 平台使用这个linux 目录下的so 转出来的bin, 可以在android 设备htp等后端运行,这点注意。
七、进一步编译得到bin 模型文件
我们使用htp 后端进行推理,可以构建一个后端backend配置文件,然后将配置文件作为输入,转换得到和硬件相关联的bin 文件,类似于c++ 代码实现中的构建context的那一步。
${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-context-binary-generator --model ./output-so/x86_64-linux-clang/libbge_real_data_qnn.so --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so --output_dir ./bin --binary_file bge_8295_qnn.serialized --config_file ./htp_backend_extension.json
配置文件如下,我配置的文件如下:
htp_backend_extension.json
{ "backend_extensions":{"shared_library_path":"/home/shengqing.liu/qaisw-v2.12.0.230626174329_59328-auto/lib/x86_64-linux-clang/libQnnHtpNetRunExtensions.so","config_file_path": "/home/shengqing.liu/model/rag-bge-base/htp_device_config.json"}
}
htp_device_config.json
{"graphs":{"vtcm_mb":8, // 片上内存设置"O":3.0, // 等级有1.0, 2.0, 3.0 , 3.0优化最大"fp16_relaxed_precision":1, // 支持fp16计算"graph_names":["bge_smiply_qnn"] //生成的so文件名中去除lib,就是图名称。},"devices":[{"device_id":0, //npu的device id, 可以不设置"soc_id":39, // 芯片系统的id."dsp_arch":"v68", // 芯片的架构"cores":[{"core_id":0,"perf_profile":"burst" //性能等级,这个是很快的设置,还有其他的。}]}]
}
sdk2.20 以后定义图配置是使用图数组,之前的版本是使用图对象的格式,所以定义图数组之后,会出现找不到key的错误。
八、运行模型
1. Linux平台运行
${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-net-run --backend ${QNN_SDK_ROOT}/lib/x86_64-linux-clang/libQnnHtp.so --model ./rag_qnn_so/x86_64-linux-clang/libreal_data_qnn.so --input_list ./input_list.txt
2. android 系统运行
将qnn的so库, 模型,数据,可执行文件push 到android系统中。
adb shell mkdir -p /data/local/tmp/bge//模型文件adb push D:\work_project\2025\bge\real_data_quant\bin\bge_8295_qnn.serialized.bin /data/local/tmp/bge_model
//输入数据
adb push D:\work_project\2025\bge\real_data_quant\real_input_data\* /data/local/tmp/bge
//输入数据地址
adb push D:\work_project\2025\bge\real_data_quant\input_data .txt /data/local/tmp/bge_model//可执行文件
adb push $QNN_SDK_ROOT/bin/aarch64-android/qnn-net-run /data/local/tmp/bge adb push $QNN_SDK_ROOT/lib/aarch64-android/libQnnHtp.so /data/local/tmp/bge
adb push $QNN_SDK_ROOT/lib/aarch64-android/libQnnHtpNetRunExtensions.so /data/local/tmp/bge
adb push $QNN_SDK_ROOT/lib/aarch64-android/libQnnHtpPrepare.so /data/local/tmp/bge
adb push $QNN_SDK_ROOT/lib/hexagon-v68/unsigned/libQnnHtpV68Skel.so /data/local/tmp/bge
adb push $QNN_SDK_ROOT/lib/aarch64-android/libQnnHtpV68Stub.so /data/local/tmp/bge
#系统so
adb push $QNN_SDK_ROOT/lib/aarch64-android/libQnnSystem.so /data/local/tmp/bge
修改/data/local/tmp/bge_model权限,然后设置环境变量,进行使用bin文件模型的运行。
chmod -R 777 /data/local/tmp/bge_model/*export LD_LIBRARY_PATH=/data/local/tmp/bge_model/:/vendor/lib64/:$LD_LIBRARY_PATH
export ADSP_LIBRARY_PATH=/data/local/tmp/bge_model./qnn-net-run --backend ./libQnnHtp.so --retrieve_context ./bge_8295_qnn.serialized.bin --input_list ./input_data.txt --output_dir output2
使用so 模型文件进行运行
./qnn-net-run --backend ./libQnnHtp.so --model ./bge_8295_qnn.so --input_list ./input_data.txt --output_dir output1
如果是int 型的输入数据,强烈建议加上--use_native_input_files. 表示读输入文件的时候按照int32读而不是float32,精度会大大改善。
相关文章:
在android 系统上qnn sdk转换,运行模型示例
前面讲了如何配置qnn sdk的环境,这一篇总结下qnn 实际转换一个onnx 模型,并运行的实现步骤。 设备: 1. ubuntu22.04 的Linux 服务器。 2. 一台android手机。 一、下载模型 from optimum.onnxruntime import ORTModelForSequenceClassifi…...
docker安装Canal1.1.5,MySQL5.7踩坑
docker安装Canal 前情提示安装MySQLdocker安装MySQL1. 拉取镜像2. 创建容器映射宿主机目录3. docker run 配置mysql重启mysql新建canal用户 安装Canal创建docker网络安装Canal1.拉取canal镜像2.创建目录3.运行容器 踩坑问题1 前情提示 关于版本问题,官方也没有详细…...
SpringBoot 接口国际化i18n 多语言返回 中英文切换 全球化 语言切换
介绍 Spring Boot通过MessageSource接口来实现国际化,它可以加载不同的消息资源文件,通常是.properties格式。通过定义不同的语言文件(例如:messages_en.properties、messages_zh.properties等),可以根据用…...
C++ 嵌套类 (详解 一站式讲解)
目录 嵌套类 嵌套类的定义 嵌套类结构的访问权限 pimpl模式(了解) 嵌套类 嵌套类的定义 首先介绍两个概念: 类作用域(Class Scope) 类作用域是指在类定义内部的范围。在这个作用域内定义的成员(包括…...
EasyCVR视频汇聚平台助力大型生产监控项目摄像机选型与应用
一、方案背景 在300路大型生产监控项目中,由于生产环境复杂多样,涵盖室外厂区、大型车间、室内办公区域等不同场景,单一类型的摄像机难以满足全方位、精细化的监控需求。EasyCVR作为一款功能强大的视频融合管理平台,具备灵活的视…...
解决leensa无法使用的办法:平替教程
Leensa已经完全连不上,并显示超时,至于之前有传言称他们会恢复服务也完全是无稽之谈。 那么,Leensa停止服务后,广大的外贸人,设计人,留学生以及技术人学习,查资料以及开发客户该怎么办呢&#…...
算法思想之哈希表
欢迎拜访:雾里看山-CSDN博客 本篇主题:算法思想之哈希表 发布时间:2025.4.28 隶属专栏:算法 目录 算法介绍哈希表作用什么时候使用哈希表怎么使用哈希表 例题两数之和题目链接题目描述算法思路代码实现 判定是否互为字符重排题目链…...
springboot 视频分段加载在线播放
页面访问视频资源 前端播放加载部分视频,每次选中一个时间点后 往后加载一部分视频,主要用以节省网络传输的数据量 通过ResourceHttpRequestHandler类实现,ResourceHttpRequestHandler支持分片加载,前端请求头中携带Range: bytes 0-10001,就…...
【题解-Acwing】868. 筛质数
题目:868. 筛质数 题目描述 给定一个正整数 n,请你求出 1∼n 中质数的个数。 输入 共一行,包含整数 n。 输出 共一行,包含一个整数,表示 1∼n 中质数的个数。 数据范围 1 ≤ n ≤ 106 时空限制 0.2s / 64MB 输入样例 8输出样例 4代码 #include...
java 和 C#操作数据库对比
Java和C#在操作数据库方面有诸多相似之处,但也存在一些差异,以下从几个方面为你进行对比: 数据库连接 Java 在Java中,使用JDBC(Java Database Connectivity)来连接数据库。连接数据库的步骤通常包括加载…...
用 Python打造交互式图片-音视频管理器:代码分析与实践
在 Python 的 GUI 开发领域,wxPython 是一个功能强大且跨平台的框架,适合快速构建桌面应用程序。本文将深入分析一个基于 wxPython 的交互式图片管理器项目(SelectModelToPlayVideoAndAudio.py),该程序允许用户管理图片…...
Django 缓存框架
动态网站的一个基本权衡是它们是动态的。每当用户请求页面时,Web 服务器进行各种计算,从数据库查询到模板渲染到业务逻辑,以创建您网站访问者看到的页面。从处理开销的角度来看,这比标准的从文件系统中读取文件的服务器安排要昂贵…...
后缀数组~
子串:在字符串s中,取任意i<j,那么在s中截取从i到j的这一段就叫做s的一个子串。 后缀:后缀就是从字符串的某个位置i到字符串末尾的子串,我们定义以s的第i个字符为第一个元素的后缀为suff(i)。 suff(1)就是从第一个字符到最后一个…...
Rust 学习笔记:编程练习(一)
Rust 学习笔记:编程练习(一) Rust 学习笔记:编程练习(一)Convert temperatures between Fahrenheit and CelsiusGenerate the nth Fibonacci numberPrint the lyrics to the Christmas carol “The Twelve …...
【基础知识】常见的计算公式(一)
目录标题 定时器相关公式1. 定时器分频系数计算2. 定时器定时时间计算 波特率相关公式1. 异步串行通信波特率计算 PWM 相关公式1. PWM 占空比计算 不知道你们是不是和我一样,对定时器中的分频系数相关的计算公式,波特率计算公式等,都有点心生畏惧,其核心原因是不清楚不了解,没有…...
【AI生产力工具】Windsurf,一款AI编程工具
Windsurf 是 Codeium 公司推出的一款 AI 编程助手,它是一款集成深度上下文感知、多模型协作和实时代码管理的综合开发环境(IDE)。 Windsurf 作为 AI 编程工具的核心价值在于 “上下文感知 + 多模型协作 + 自动化工作流”,其深度集成的智能体系统(如 Flows 和 Cascade)正…...
【网络原理】TCP提升效率机制(三):延时应答和捎带应答
目录 一. 延时应答 二. 捎带应答 一. 延时应答 延时应答也是基于滑动窗口的一种提升传输效率的方式(减少ACK数量) 接收方收到数据之后,不会立刻返回一个ACK确认报文,而是等一会再返回ACK报文 这样做的好处? 1&…...
Golang|分布式索引架构
当文档数量巨大时,如一亿个文档,倒排索引难以全部放入单机内存。正排索引将热数据和冷数据分别存储在内存和磁盘中。分布式搜索引擎将数据分布在不同服务器上以应对大量数据。 倒排索引的水平切分 水平切分按关键词划分数据,如JAVA和算法在A服…...
【蓝桥杯省赛真题58】Scratch画台扇 蓝桥杯scratch图形化编程 中小学生蓝桥杯省赛真题讲解
目录 scratch画台扇 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 四、程序编写 五、考点分析 六、推荐资料 1、scratch资料 2、python资料 3、C资料 scratch画台扇 第十五届青少年蓝桥杯scratch编程省赛真题解析 一…...
WebRTC SDK是什么?
语音环境每年都在变,OKCC以前代理商的客群都是简单高效外呼为主,今年发现变化很大。很多代理商做的终端客户都是给其他业务系统赋能为主了。主流的还是以API对接为主,但是对接中发现webrtc SDK使用频率很高。 那么什么是WebRTC SDK…...
反向代理、负载均衡与镜像流量:原理剖析、区别对比及 Nginx 配置实践
在现代网络架构中,反向代理、负载均衡和镜像流量是保障系统高效、稳定、安全运行的关键技术。虽然它们都涉及网络流量的管理与分发,但在功能、应用场景和实现方式上有着显著差异。本文将深入探讨三者的区别,并结合 Nginx 这一强大的开源服务器…...
PyCharm 2023升级2024 版本
windows下把老版本卸载之后,需要把环境变量,注册表信息删除。 并且把C:\Users\用户\AppData 文件夹下的 Local\JetBrains和Roaming\JetBrains 都删除,再重新安装 原旧项目升级的方式: 1.2023虚拟机的文件夹是venv 改为.venv…...
for(auto it: vec)和for(auto it: vec)的区别以及使用场景
目录 1.for(auto it: vec) 2.for(auto& it: vec) 3.总结 在 C 里,for(auto it: vec) 和 for(auto& it: vec) 都属于基于范围的 for 循环,可用于遍历容器(像 std::vector、std::list 等)或者数组。不过,它们…...
系统思考提升培训效能
彼得德鲁克曾说:管理者的价值,不在于处理了多少事务,而在于创造了多少不可替代的成果。效率是以正确的方法做事,效能则是做正确的事。在系统思考中我们看到:效率往往是对单点问题的反应,而效能则是对整体系…...
第1篇:Egg.js框架入门与项目初始化
一、Egg.js框架优势与设计理念 1. 为什么选择Egg.js? 作为基于Koa 2.x的渐进式企业级框架,Egg.js在阿里系大规模生产环境中验证成熟,具备以下核心优势: 约定优于配置 通过app/config目录结构自动加载机制,减少冗余配置…...
CMU-15445(1)——环境搭建
前言 最近在找完暑期实习之后,终于有了一些干项目外的空余时间学习新的知识,在这么多轮面试中,数据库的考察非常多,但孱弱的数据库基础导致我有很多次面试被问住,因此我希望在学习CMU-15445(Fall 2024&…...
Web基础与HTTP协议
目录 一:Web基础 1.域名和dns 1.1域名的概念 (1)域名的结构 (2)域名结构类型 2.Hosts文件 (1)hosts文件的作用 (2)修改hosts文件 3.DNS 4.域名注册 ࿰…...
数量关系7_行程问题
目录 一、基础行程1. 基础行程2. 比例法运用3. 相遇追及二、特殊情境1. 多次相遇问题(简单)2. 流水问题3. 火车过桥4. 等距离平均速度问题(简单)5. 匀加速一、基础行程 1. 基础行程 公式1:S = Vt 公式2:平均速度=(2 V1V2) / (V1+V2) 例题3(2023 广东) 某地举办了“铁…...
MTK Android12-13 App卸载加锁
实现:App 卸载时候需要加一层拦截锁,客户输入密码后才能正常卸载 文章目录 参考资料:实现方案涉及到修改文件修改方案实现效果 源码分析- 卸载方式一) 设置界面进行卸载InstalledAppDetailsAppInfoDashboardFragmentAppButtonsPre…...
文号验证-同时对两个输入框验证
文号验证-同时对两个输入框验证 效果: 一、如果有多个文号: <div v-for"(item, index) in approvalForm.productApprovalTypeEvents" :key"index"> <el-form-itemlabel"文号":prop"productApprovalTypeEv…...
嵌入式面试八股文(十二)·FreeRTOS中·堆和栈
目录 1. 堆和栈 1.1 堆 1.2 栈 1.3 堆和栈的区别 1.3.1 分配方式 1.3.2 分配效率 1.3.3 生长方向 1.3.4 空间管理 1.3.5 存放内容 1. 堆和栈 1.1 堆 堆是一块用于动态分配内存的区域,用于存储程序运行时动态创建的对象。堆的大小可以在程序运行…...
表的增删改查
目录 1、增删改查(CRUD) 2、新增(C) 3、查询(R) 3.1、全列查询 3.2、指定列查询 3.3、查询字段为表达式 3.4、别名 3.5、去重:distinct 3.6、查询时排序 1、增删改查(CRUD&…...
软考-软件设计师中级备考 4、数据结构
1、数据结构三要素 要素定义分类特点逻辑结构数据元素之间的逻辑关系,是从具体问题抽象出来的数学模型,与数据存储无关1. 集合结构:数据元素同属一个集合,无其他特殊关系 如一盒麦丽素豆子 2. 线性结构:元素存在一对…...
CMake:设置编译C++的版本
CMake提供了CMAKE_CXX_STANDARD用于设置C++的版本,比如可以通过如下方式设置使用C++23 set(CMAKE_CXX_STANDARD 23) 同时也提供了CMAKE_CXX_STANDARD_REQUIRED可以要求强制使用某个C++版本,比如: set(CMAKE_CXX_STANDARD_REQUIRED ON) 如果设置为 `ON`,那么 CMake 会要求编…...
【angular19】入门基础教程(一):项目的搭建与启动
angular现在发展的越来越能完善了,在vue和react的强势竞争下,它迎来了自己的巨大变革。项目工程化越来越好,也开始拥抱了vite这种高效的构建方式。所以,我们有必要来学习这么一个框架了。 项目实现效果 nodejs环境 Node.js - v^…...
在使用Python的Selenium库打卡网页后,通过CDP命令获取所有cookies(包括Httponly和Secure的cookies)
通过 Chrome DevTools Protocol (CDP) 结合 Selenium 可以直接获取浏览器存储的所有 Cookies(包括所有域名下的 Cookies),以下是详细步骤: 步骤 1:配置 Chrome 启用 CDP启动 Chrome 浏览器时需启用远程调试端口&#…...
Deepseek-v3+cline+vscode java自动化编程
1、Deepseek DeepSeek 充值后,创建apikey 2、vscode Visual Studio Code - Code Editing. Redefined 3、下载插件cline 4、配置deepeseek-v3 的密钥到cline 5、不可用 在开始的几次调用能正常使用起来,用了几次后,不能使用了,请求…...
5G育种技术之植物性状订制
行业展望 我国农作物种业市场规模逐年增长,其中以粮食作物种子市场规模较大。目前我国育种产业发展仍处于初级阶段,存在龙头企业市场占有率和行业集中度不高、企业育种技术和水平落后于发达国家、种企研发投入不足等问题。虽然基因编辑技术的出现有望改…...
12前端项目----添加购物车1.0
商品添加购物车 商品数量添加购物车浏览器本地存储localStoragesessionStorage添加成功页面 商品数量 输入为数字,最少为1<div class"cartWrap"><div class"controls"><input autocomplete"off" class"itxt&quo…...
Elastic Platform 8.18 和 9.0:ES|QL Lookup Joins 功能现已推出,Lucene 10!
作者:来自 Elastic Elastic Platform Team Elastic 最新发布的 8.18 和 9.0 版本包含了强大的更新,将显著提升你的体验、增强查询性能并优化日志管理。无论你是在处理搜索、可观察性还是安全用例,本次发布都带来了大量新特性,旨在…...
两地三中心
1. 什么是同城备份 ✅ 定义: 主机房和备份机房都在同一座城市,通常距离几十公里以内(比如10-50公里)。 ✅ 特点: 网络延迟很低(毫秒级),可以做到实时同步/热备份。 恢复速度快&am…...
数据结构第七章(一)-顺序查找和折半查找
数据结构第七章(一) 顺序查找和折半查找一、查找1.平均查找长度(ASL) 二、顺序查找1.实现2.算法优化 三、折半查找1.实现2.查找判定树 四、分块查找1.算法思想2.查找效率分析(ASL) 总结 顺序查找和折半查找…...
springboot项目之websocket的坑:spring整合websocket后进行单元测试后报错的解决方案
前排提醒:还是博主菜,见识短浅,没遇到过这个问题。。。 起因 前段时间学习websocket和sse,写demo用了spring框架。后来又写了新的spring单元测试类demo去测试,结果启动后报错,报错信息提示websocket的相关…...
在单片机编程中充分使用抽象工厂模式,确保对象创建的限制,多使用抽象接口避免多变具体实现类
背景 在软件架构设计上追求稳定,就必须多使用稳定的抽象接口,少依赖多变的实现;具体编码时可以充分使用抽象工厂模式 举例进行详细讲解和说明抽象工厂模式在单片机开发中的应用 抽象工厂模式是一种创建型设计模式,它提供了一种方式,可以将一组相关的对象创建封装到一个…...
喷泉码技术在现代物联网中的应用的总结和参考文献
总结 物联网与 5G 技术高速发展,数据传输对可靠性和实时性提出严苛要求。前向纠错码是增强通信鲁棒性的关键,但平衡冗余资源开销与编解码效率的矛盾是核心难题。LT 码和 Raptor 码是无率码典型。理论上它们能达渐进最优性能,然而实际系统受数据包规模、计算资源等限制,其工…...
vuex与vuex-persistedstate 插件固化数据
一,vuex与vuex-persistedstate 插件固化数据 的小案例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>Vuex基础案例</title></head><body><div id"app"&…...
如何在WordPress网站中设置双重验证,提升安全性
随着互联网的不断进步,网站的安全问题越来越受到重视。尤其对于WordPress这样常用的建站平台,安全性显得尤为重要。尽管WordPress自带一定的安全性,但仅依靠用户名和密码的登录方式仍然存在风险。因此,启用“双重验证”便成为了提…...
2025系统架构师---基于规则的系统架构风格
引言 在业务规则频繁变更、决策逻辑高度动态化的现代企业环境中,基于规则的系统架构风格(Rule-Based System Architecture Style)通过将核心业务逻辑抽象为可配置规则、规则引擎与决策服务的分离,实现了业务敏捷…...
Python排序中lambda函数详解
在 Python 中,lambda 函数是一种匿名函数,通常用于需要一个函数但又不想为其定义一个正式名称的情况。在排序操作中,lambda 函数用于指定排序的依据。 lambda 函数的基本语法 lambda 函数的基本语法如下: lambda arguments: ex…...
web 基础与 http 协议
目录 一 Web 基础 1. 域名和 DNS 1.1 域名的概念 1.2 DNS 2. 网页与HTML 2.1 HTML 概述 2.2 HTML 基本标签 2.3 网站和主页 3. 静态网页与动态网页 3.1 静态网页 3.2 动态网页 二 HTTP 协议 1. HTTP 协议概述 2. HTTP 方法 3. HTTP 状态码 4. HTTP 请求流程分析…...