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

基于大语言模型知识问答应用落地实践 – 知识库构建(下)

2c7249a72552401a36dcbc72cacf01d6.gif

上篇介绍了构建知识库的大体流程和一些优化经验细节,但并没有结合一个具体的场景给出更细节的实战经验以及相关的一些 benchmark 等,所以本文将会切入到一个具体场景进行讨论。

目标场景:对于 PubMed 医疗学术数据中的 1w 篇文章进行知识库构建,实现快速的注入和查询速度。

主要讨论的内容会覆盖 OpenSearch 集群规模设计、知识库 Index 设计以及实验步骤细节。

01

资源推算

一般来说,我们需要按照以下 OpenSearch 集群的设计指导原则,选择 OpenSearch 的资源配置:

  • 如果偏向搜索的工作负载那么应该使用 10-30GB 的 shard 大小,如果偏向日志的工作负载,应该采用 30-50GB 的节点大小;

  • 请尝试将分片数量设为数据节点数量的偶数倍,有助于分片在数据节点上均匀分布;

  • 每个节点的分片数,与 JVM 堆内存成正比,每 GB 内存的分片不超过 25 个;

  • 每个 5 个 vCPU 能对应一个分片,比如 8 个 vCPU 则最多支持 6 个 shard;

  • 如果有启用 k-NN 字段,参考如下表格进行内存的推算。

0e090e93f7306e1787c185ee81d35562.png

依据目前的信息,仅仅知道所要索引的原始文档数。由于文档切分等中间处理过程,无法估算具体的内存用量和存储量,所以需要用小批量的实验数据进行测试推演。

在小批量实验中尝试索引了 300 篇文档,通过切分共产生出了约 203k 条记录,4.5GB 存储量。那么按比例换算如果需要索引 1 万篇文档,那么会产生约 700w 记录,150GB 存储。如下图所示:

2a6b4f0b747c79bd9fceea85cf3ae749.png

从知识问答 Chatbot 场景出发,属于搜索的工作负载,Shard 的大小应在 10-30GB 范围内以增加搜索性能。shard 数量一般遵循节点数的倍数的原则,假设是 2 节点集群那么可以是 [2, 4, 8, 16 …]。以 150GB 存储总量进行计算,shard 可以为 8, 10, 12, 14, 16,当 shard 数为 8 时,每个 shard 存储量为 18.75GB,符合要求。


向量检索方面为了同时保证 recall 和 latency,采用了 HNSW 算法。另外参考  中的 benchmark 结论,HNSW 算法中 m 值可以设定为 16。那么内存规划方面,依照上表公式进行内存占用的推算:

35fa456797b5134b98326723d545ed39.png

一般每个节点的堆外内存占比 50%,根据knn.memory.circuit_breaker.limit=70% 的最佳实践设定,那么 35% 的节点内存被 KNN 占用,那么推算出整个节点的内存应为 22.9GB / 35% = 65GB。


vCPU 的规划方面,假设 shard 数为 8,乘以 1.5vCPU/Shard 的系数,vCPU 个数至少需要为 12 以上。结合如下 C 系和 R 系的实例配置信息和价格信息,综合考虑内存和 vCPU 的要求,选择 C 系的 2 节点 c6g.4xlarge 或者 R 系的 2 节点 r6g.2xlarge。

77a138c280152f117f400d57545d7394.png

02

索引构建实验

索引构建中需要关注的主要有三点:

  • 数据完整性,保证所有的知识都能被查询到,不会因为摄入异常导致数据缺失。

  • 构建速度,知识召回部分可能存在反复的效果调整,需要反复多次摄入,速度对全链路开发调优的效率很重要。

  • 查询性能,保证场景中的实时会话体验。

整个摄入过程,从过程上基本可以划分为三个阶段:文本切分、文本向量化以及摄入 Amazon OpenSearch。其中文本切分和文本向量化的处理是临时性的工作负载,原则上可以提升 glue job 的并发数和 Amazon SageMaker Endpoint 背后的节点数来线性提高对这块工作负载的处理速度,但 OpenSearch 属于一个预分配的资源(注:今年即将发布的 OpenSearch Severless k-NN 向量数据库会改变这一点)。后两个部分,即向量化和 OpenSearch 摄入可能会是整个流程的瓶颈,完整流程测试不容易进行拆解分析性能瓶颈,所以本试验会分别对这两部分进行测试。

实验 1 – Embedding Model 吞吐测试

  1. 使用 paraphrase-multilingual-deploy.ipynb 进行部署,部署 10 台 g4dn.xlarge 机型;

    https://github.com/aws-samples/private-llm-qa-bot/blob/main/notebooks/embedding/paraphrase-multilingual-deploy.ipynb

  2. 注释掉下游写入 OpenSearch 造成的影响,暂时注释掉相关代码;

    https://github.com/aws-samples/private-llm-qa-bot/blob/main/code/aos_write_job.py

  3. 利用 batch_upload_docs.py 启动多 glue job 进行并发运行。

    https://github.com/aws-samples/private-llm-qa-bot/blob/main/code/batch_upload_docs.py

这部分处理流程中,通过调整 glue job 的并行度与 client-side batch size 可以调整向量化这一步骤的吞吐能力。当 GPU 利用率不足时,提高 client-side batch size 能够提高 GPU 的利用率。经过简单测试发现,确实能证明这个假设,具体数据可以参考如下实验结果:

856c08ab8307016df1490e7d97dba4dd.png

实验 2 – Amazon OpenSearch 摄入测试

1. 随机生成向量,替换掉 Embedding 模型调用,参考如下代码:

import numpy as np
AOS_BENCHMARK_ENABLED=Truedef get_embedding(smr_client, text_arrs, endpoint_name=EMB_MODEL_ENDPOINT):if AOS_BENCHMARK_ENABLED:text_len = len(text_arrs)return [ np.random.rand(768).tolist() for i in range(text_len) ]# call sagemaker endpoint to calculate embeddings...return embeddings

左滑查看更多

2. 构建 OpenSearch 集群以及索引,并优化设置;

a. 构建对应的索引

向量字段涉及到的两个参数 ef_construction 和 m。ef_construction 指定构建 k-NN 图的时候的动态列表大小,值越大其向量数据的图更精确,但索引的速度也响应更慢。m 指定 k-NN 中每个向量双向链表的数量,越大检索越准确,但相应内存占用会显著增大。参考博客<Choose the k-NN algorithm for your billion-scale use case with OpenSearch>中的 benchmark 结论 (https://aws.amazon.com/cn/blogs/big-data/choose-the-k-nn-algorithm-for-your-billion-scale-use-case-with-opensearch/),对于当前的数据规模,参数 ef_construction:128 和 m:16 已经足以保证召回率,另外在构建索引时可以关注以下几点:

  1. 添加一个 publish_date 字段方便后续根据时间来删除/更新知识;

  2. 添加 idx 整型字段用于记录对应片段在全文中的顺序,在召回时可以基于 range_search 召回相邻上下文片段;

  3. 只做过滤不做关键字召回的字段设置成 keyword 类型,有利于索引速度。具体可以参考如下代码:

PUT chatbot-index
{"settings" : {"index":{"number_of_shards" : 8,"number_of_replicas" : 0,"knn": "true","knn.algo_param.ef_search": 32,"refresh_interval": "60s"}},"mappings": {"properties": {"publish_date" : {"type": "date","format": "yyyy-MM-dd HH:mm:ss"},"idx" : {"type": "integer"},"doc_type" : {"type" : "keyword"},"doc": {"type": "text","analyzer": "ik_max_word","search_analyzer": "ik_smart"},"content": {"type": "text","analyzer": "ik_max_word","search_analyzer": "ik_smart"},"doc_title": {"type": "keyword"},"doc_category": {"type": "keyword"},"embedding": {"type": "knn_vector","dimension": 768,"method": {"name": "hnsw","space_type": "cosinesimil","engine": "nmslib","parameters": {"ef_construction": 128,"m": 16}}           }}}
}

左滑查看更多

b.设置 knn 相关参数,参考《基于大语言模型知识问答应用落地实践 – 知识库构建(上)》

PUT /_cluster/settings
{"transient": {"knn.algo_param.index_thread_qty": 8,"knn.memory.circuit_breaker.limit": "70%"}
}

左滑查看更多

c.开启多 glue job 进行并发摄入,可以参考如下代码:

# 注意${Concurrent_num} 不能超过
# glue job->job detail->Advanced properties->Maximum concurrency 设置中最大限制
python batch_upload_docs.py \
--bucket "${bucket_name}" \--aos_endpoint "${OpenSearch_Endpoint}" \--emb_model_endpoint "${EmbeddingModel_Endpoint}" \--concurrent_runs_quota ${Concurrent_num} \--job_name "${Glue_jobname}"

左滑查看更多

3. 部分实验结果明细


每轮实验中,调整的参数已经用加粗字体标注出来,供参考用于指导后续的数据注入中的参数调整。

0a67305bfdcda94a9c9bc79ad8e4aad4.png

实验 3 – 全流程摄入测试

a. 部分实验记录明细

b23463714bf5e762dd17a65743babf01.png

b. 初步实验结论


参考以上的实验记录可知,1 万篇文档拆分成 700 万条向量后,通过调整客户端并发,推理端点的节点数和推理 Batch Size 可以在 1 小时左右完成摄入,且完整性没有问题。能够满足大规模知识构建的要求,如果文档量继续增长,可以继续扩展 OpenSearch 节点和 SageMaker Endpoint 节点。

03

索引构建经验总结

以往 OpenSearch 摄入时的一些最佳实践中并不包含 knn 的情况,所以在 knn 索引存在的情况,不能完全参照之前的结论,通过以上三种不同的实验方式,在多次实验的过程中,本文得到了以下的一些实践经验和结论,供参考:

a. CPU 利用率和参数 ef_construction 与 m 明显正相关,在实验中使用较大的 ef_construction 和 m 时,CPU 很容易达到 100%。实验中,在其他参数相同的情况下,ef_construction 为 512 时,CPU 利用率会长期保持在 100%,改为 2 时,利用率基本在 20% 以下,峰值不超过 30%。

b. 客户端并行数量与 OpenSearch 的摄入速度和负载成正相关,但并不是线性相关。多客户端能提高摄入速度,但是客户端数量过多,可能会导致大量的(429, ‘429 Too Many Requests /_bulk’)和(503, “No server available to handle the request..”)等错误。

c. 指数退避重试机制能保证摄入的完整性以及因集群瞬时不可用导致的大面积写入失败,opensearch-py包中有如下摄入函数, 如果并发客户端过多,可能会导致CPU利用率一直位于100%,在max_retries的重试次数内,每次会等待 initial_backoff * (attampt_idx ** 2)的时间,通过设定一个较大的initial_backoff等待时间,能避免在客户端并发数偏大的情况下出现大面积429错误。另外客户端数也不能过大,否则也会更容易出现大量的503相关错误。对于偶发的503报错,可以利用 glue 的 retry 机制处理,保证写入的完整性。

# chunk_size 为文档数 默认值为 500
# max_chunk_bytes 为写入的最大字节数,默认 100M 过大,可以改成 10-15M
# max_retries 重试次数
# initial_backoff 为第一次重试时 sleep 的秒数,再次重试会翻倍
# max_backoff 最大等待时间
response = helpers.bulk(client,doc_generator,max_retries=3,initial_backoff=200, #默认值为 2,建议大幅提高max_backoff=800,max_chunk_bytes=10 * 1024 * 1024) #10M 社区建议值

左滑查看更多

注意:在大规模数据摄入的生产场景中,不建议使用LangChain提供的向量数据库接口,查看其源码可知,LangChain的默认实现是单客户端,且其内部实现没有使用指数退避Retry机制,无法保证摄入速度和完整性。

d. 写入完成后,建议查询文档的去重数量,确保写入的完整性。可以在 OpenSearch Dashboard 的 Dev tools 中使用如下的 DSL 语句查询文档总数。注意 cardinality 方式的统计不是精准统计值,可以提高 precision_threshold 参数值来提高其准确性。

POST /{index_name}/_search
{"size": 0,"aggs": {"distinct_count": {"cardinality": {"field": "{field_name}","precision_threshold": 20000}}}
}=> 10000

左滑查看更多

同时可以按照文档名统计对应的 chunk 数量,可以帮助发现潜在文档处理质量问题,参考下面代码:

GET /{index_name}/_search
{"size": 0,"aggs": {"distinct_values": {"terms": {"field": "doc_title"}}}
}=>
...
"aggregations": {"distinct_values": {"buckets": [{"key": "ai-content/batch/PMC10000335.txt","doc_count": 42712},{"key": "ai-content/batch/PMC10005506.txt","doc_count": 5279},...{"key": "ai-content/batch/PMC10008235.txt","doc_count": 9},{"key": "ai-content/batch/PMC10001778.txt","doc_count": 1}]}

左滑查看更多

e. refresh_interval 设置为 -1,在其他相关参数的相同的情况下,503 报错明显增加。更改为 60s 后,情况有明显好转, 如果发生类似问题,可以做类似的调整。

04

检索性能调优

数据注入完毕以后,直接查询性能是十分差的,查询时延可能在几秒甚至十几秒。需要进行一些必要的优化。核心的主要有两点:

a. Segment 合并

Segment 是 OpenSearch 中的最小搜索单元。如果每个 shard 只有 1 个 segment,搜索效率将达到最高。为了实现这个目标,我们可以通过控制 refresh interval 来降低小 segment 的生成速度,或者手动进行 segment merge。这将有助于减少搜索过程中的开销,提高搜索速度。


可以在 OpenSearch Dashboard 的 Dev tools 中通过如下的 DSL 执行合并,整个合并过程比较长,执行之前可以调高用于合并的线程最大值,能够提高合并的速度。

# merge segments
POST /{index_name}/_forcemerge?max_num_segments=1?pretty# increase max_thread_count for merge task
PUT {index_name}/_settings
{"index.merge.scheduler.max_thread_count": 8
}

左滑查看更多

合并前后可以执行如下 DSL 来检查当前的 segments 情况:

GET _cat/segments/{index_name}?v&h=index,segment,shard,docs.count,docs.deleted,size

左滑查看更多

以下表格是合并 segments 后的情况,合并完成后每个 shard 下仅有一个 segment,数据也均匀分布,标记删除的数据也被清理掉了。

2280832ca0fc4e381329dcba16772268.png

b. k-NN 索引 warmup


由于 k-NN 索引的性能与索引数据结构是否缓存到内存中密切相关,能够提供的缓存内容容量对性能影响很大。可以执行以下 DSL 命令,对 k-NN 索引进行预热

GET /_plugins/_knn/warmup/{index_name}?pretty

左滑查看更多

预热执行很快,预热完毕以后,性能会有明显改善。可以到 CloudWatch 中去查看 OpenSearch Domain 中的 KNNGraphMemoryUsagePercentage 指标进行确认是否执行完毕,如图所示:

a533dbd3c3b0f2c01655278dee477a6b.png

05

结语

本文在本系列上篇博客的基础上,通过一个真实数据场景的实践进行更详细的阐述,讨论的重点更多放在针对大规模的文档、更快更完整地构建基于向量数据的知识库上面,这对于一些行业如金融、法律、医疗等行业知识库的构建具备指导借鉴意义。

本文的第一部分对于 Amazon OpenSearch 的集群配置选择给出了一些方法参考,第二三四部分对于数据摄入和检索性能等方面给出了一些初步的经验总结。


本系列后续还有几篇相关博客进一步深入阐述,其中包括:

  • 《Amazon OpenSearch 向量数据库的性能评估与选型分析》,会针对 Amazon OpenSearch 作为向量数据库,讨论其优势及定位,在索引和查询等方面给出更加详细的 benchmark,给用户更加丰富的参考信息。

  • 《基于大语言模型知识问答应用落地实践 – 知识召回调优》,会在知识库构建的前提和背景下,讨论如何更好的召回对应的知识,包括各种适用的召回手段和实践技巧。另外,本文提到的代码细节可以参考配套资料:

  1. 代码库 aws-samples/private-llm-qa-bot

    https://github.com/aws-samples/private-llm-qa-bot

  2. workshop <基于 Amazon OpenSearch+大语言模型的智能问答系统>(中英文版本)

    https://github.com/aws-samples/private-llm-qa-bot

参考文献:

1. Choose the k-NN algorithm for your billion-scale use case with OpenSearch

https://aws.amazon.com/cn/blogs/big-data/choose-the-k-nn-algorithm-for-your-billion-scale-use-case-with-opensearch/

本篇作者

ddf3de8a09c31b00d4e582af34580c49.jpeg

李元博

亚马逊云科技 Analytic 与 AI/ML 方面的解决方案架构师,专注于 AI/ML 场景的落地的端到端架构设计和业务优化,同时负责数据分析方面的 Amazon Clean Rooms 产品服务。在互联网行业工作多年,对用户画像,精细化运营,推荐系统,大数据处理方面有丰富的实战经验。

945c64d9a27d6fee0931db2325354d80.jpeg

孙健

亚马逊云科技大数据解决方案架构师,负责基于亚马逊云科技的大数据解决方案的咨询与架构设计,同时致力于大数据方面的研究和推广。在大数据运维调优、容器解决方案,湖仓一体以及大数据企业应用等方面有着丰富的经验。

85b0292672727820473211f848fd42d4.jpeg

汤市建

亚马逊云科技数据分析解决方案架构师,负责客户大数据解决方案的咨询与架构设计。

6928836329e6341e8b3d3354b57ac5b2.jpeg

郭韧

亚马逊云科技 AI 和机器学习方向解决方案架构师,负责基于亚马逊云科技的机器学习方案架构咨询和设计,致力于游戏、电商、互联网媒体等多个行业的机器学习方案实施和推广。在加入亚马逊云科技之前,从事数据智能化相关技术的开源及标准化工作,具有丰富的设计与实践经验。

27b8e557639989c59b677061a3edc90b.gif

92d5339b4c29278dc9a33659166cd110.gif

听说,点完下面4个按钮

就不会碰到bug了!

49a84d74478e1e8514b6421a5f88514c.gif

相关文章:

基于大语言模型知识问答应用落地实践 – 知识库构建(下)

上篇介绍了构建知识库的大体流程和一些优化经验细节&#xff0c;但并没有结合一个具体的场景给出更细节的实战经验以及相关的一些 benchmark 等&#xff0c;所以本文将会切入到一个具体场景进行讨论。 目标场景&#xff1a;对于 PubMed 医疗学术数据中的 1w 篇文章进行知识库构…...

Hive UDF自定义函数上线速记

0. 编写hive udf函数jar包 略 1. 永久函数上线 1.1 提交jar包至hdfs 使用命令or浏览器上传jar到hdfs,命令的话格式如下 hdfs dfs -put [Linux目录] [hdfs目录] 示例: hdfs dfs -put /home/mo/abc.jar /tmp1.2 将 JAR 文件添加到 Hive 中 注意hdfs路径前面要加上hdfs://na…...

【nacos】【sentinel】【gateway】docker-compose安装及web项目部署

docker安装 【centos】【docker】安装启动 docker-compose安装 【docker-compose】安装使用 配置文件 version: 2 networks: #自定义网络myapp&#xff0c;为了只有这些服务可以在该网络内相互访问myapp:driver: bridge services: #将容器抽象成服务nacos: #注册中心image…...

用idea查看sqlite数据库idea sqlite

1、安装Database Navigator插件 2、导入数据库并查看 3、删除数据库连接 在此做个笔记...

流媒体服务器与视频服务器有什么区别?

流媒体服务器与视频服务器有什么区别&#xff1f; 流媒体服务器用在远程教育&#xff0c;视频点播、网络电台、网络视频等方面。 直播过程中就需要使用流媒体服务器&#xff0c;一个完整的直播过程&#xff0c;包括采集、处理、编码、封包、推流、传输、转码、分发、解码、播放…...

03-基础例程3

基础例程3 01、外部中断 ESP32的外部中断有上升沿、下降沿、低电平、高电平触发模式。 实验目的 使用外部中断功能实现按键控制LED的亮灭 按键按下为0。【即下降沿】 * 接线说明&#xff1a;按键模块-->ESP32 IO* (K1-K4)-->(14,27,26,25)* * …...

Vue结合ElementUi修改<el-table>表格的背景颜色和表头样式

本项目在开发过程中vueelementui &#xff0c; 页面中使用了table表格的样式&#xff0c; 需要对原先的样式进行修改&#xff0c;以下是简单的修改样式内容&#xff1a;项目中某个 html中引用的table表格内容,定义了div的class : device_err :<div class"device_err&q…...

git clone与git pull区别

从字面意思也可以理解&#xff0c;都是往下拉代码&#xff0c;git clone是克隆&#xff0c;git pull 是拉。 但是&#xff0c;也有区别&#xff1a; 从远程服务器克隆一个一模一样的版本库到本地, 复制的是整个版本库&#xff0c;叫做clone.&#xff08;clone是将一个库复制到你…...

MyBatis学习简要

目录 什么是MyBatis? MyBatis实现的设想 MyBatis基于配置文件的开发步骤 mybatis的配置文件 Mapper代理开发 配置文件完成增删改查的三步 注解开发 一、条件查询 参数接收时&#xff0c;参数的设置&#xff1a; 动态条件查询&#xff1a; 二、添加功能 步骤&#xf…...

forlium 笔记 Map

用于创建交互式地图 1 主要参数 1.1. location 地图位置 地图的经纬度 import foliumm folium.Map(location[31.186358, 121.510256],zoom_start15)m 1.2 tiles 内置样式 默认是OpenStreetMap 1.2.1 Stamen Terrain 它强调了地形特征&#xff0c;如山脉、河流和道路 m …...

解读亚马逊云科技语义搜图检索方案

图像检索&#xff08;包括文搜图和图搜图&#xff09;是各个行业中常见的一个应用场景。比如在电商场景中&#xff0c;基于以图搜图做相似商品查找&#xff1b;在云相册场景中&#xff0c;基于文搜图来找寻所需的图像素材。 传统基于标签的图像检索方式&#xff0c;即先使用目标…...

git基本使用

1、创建仓库&#xff0c;提交代码 Git 全局设置&#xff1a; git config --global user.name "许歌" //全局绑定用户名 git config --global user.email "12075507xu-ge111user.noreply.gitee.com" //全局绑定邮箱创建 git 仓库&#xff1a; mkdir t…...

为C# Console应用化个妆

说到Windows的cmd&#xff0c;刻板印象就是黑底白字的命令行界面。跟Linux花花绿绿的界面比&#xff0c;似乎单调了许多。但其实C#开发的Console应用也可以摆脱单调非黑即白的UI。 最近遇到个需求&#xff0c;要在一堆纯文本文件里找指定的关键字&#xff08;后续还要人肉判断…...

VUE环境下 CSS3+JS 实现发牌 翻牌

创建牌容器&#xff08;关键点&#xff1a;overflow&#xff1a;hidden&#xff09;&#xff1a; <div class"popup-box"></div> .popup-box {position: absolute;width: 100vw;height: 100vh;top: 0px;left: 0;overflow: hidden; } 创建每一张牌《固…...

WSL Opencv with_ffmpeg conan1.60.0

我是ubuntu18. self.options[“opencv”].with_ffmpeg True 关键是gcc版本需要conan支持&#xff0c;比如我的是&#xff1a; compilergcc compiler.version7.5 此外还需要安装系统所需库&#xff1a; https://qq742971636.blog.csdn.net/article/details/132559789 甚至来…...

Android中正确使用Handler的姿势

在Android中&#xff0c;Handler是一种用于在不同线程之间传递消息和任务的机制。以下是在Android中正确使用Handler的一些姿势&#xff1a; 1. 在主线程中创建Handler对象 在Android中&#xff0c;只有主线程&#xff08;也称为UI线程&#xff09;可以更新UI。因此&#xff…...

webSocket前后端交互pc端版

前端代码 <!--* Author: 第一好帅宝* Date: 2023-08-29 16:12:26* LastEditTime: 2023-08-29 16:54:50* FilePath: \websocket\ceshi.html --> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&…...

Java-day13(枚举与注解)

枚举与注解 枚举 1.自定义枚举 如果枚举只有单个成员&#xff0c;则可以作为单例模式的实现方式 public class test{ public static void main(String[] args) { Season spring Season.spring;System.out.println(spring);spring.show();System.out.println(…...

vue PDF或Word转换为HTML并保留原有样式

方法一 要将PDF或Word转换为HTML并保留原有样式&#xff0c;可以使用pdfjs-dist和mammoth.js这两个库。首先需要安装这两个库&#xff1a; npm install pdfjs-dist mammoth.js然后在Vue项目中使用这两个库进行转换&#xff1a; import * as pdfjsLib from pdfjs-dist; impor…...

华硕笔记本摄像头倒置怎么办?华硕笔记本摄像头上下颠倒怎么调整

笔记本电脑相较于台式电脑&#xff0c;更易携带&#xff0c;解决了很大一部分人的使用需求。但是笔记本电脑也存在很多不足&#xff0c;比如华硕笔记本电脑就经常会出现摄像头倒置的错误&#xff0c;出现这种问题要如何修复呢&#xff1f;下面就来看看详细的调整方法。 华硕笔记…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

深入解析 ReentrantLock:原理、公平锁与非公平锁的较量

ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...