GPU加速向量搜索实战:cuVS核心原理与CAGRA算法应用

news2026/5/11 4:20:32
1. 从CPU到GPU向量搜索的范式转移与cuVS的诞生如果你最近在折腾大模型应用、推荐系统或者任何需要处理海量高维数据的项目那么“向量搜索”这个词对你来说一定不陌生。简单来说它就是把文本、图片、音频这些非结构化数据通过模型转换成一组数字也就是向量然后通过计算向量之间的“距离”或“相似度”来找到最相关的内容。这听起来很美好但当你手头有上亿条数据每条数据都是成百上千维的向量时问题就来了传统的CPU计算方式哪怕用上最先进的算法一次查询也可能需要几秒甚至几十秒这在高并发、低延迟的业务场景下是完全不可接受的。这就是GPU加速计算登场的时刻。过去十几年GPU在图形渲染和深度学习训练中证明了其恐怖的并行计算能力。而向量搜索本质上就是大规模的矩阵运算和距离计算这恰恰是GPU最擅长的事情。cuVS的出现正是将这种能力从理论带入了工程实践。它不是第一个做GPU向量搜索的库但它是目前生态最完整、设计最工程化、并且背靠NVIDIA RAPIDS庞大生态的那个“实力派”。我第一次接触cuVS是在为一个内部知识库构建RAG检索增强生成系统时当我把基于CPU的Faiss索引切换到cuVS后索引构建时间从小时级缩短到了分钟级查询延迟更是从百毫秒级降到了个位数毫秒那种性能提升带来的震撼至今记忆犹新。那么cuVS到底是什么你可以把它理解为一个专为GPU设计的“向量计算引擎”。它的核心目标非常明确提供一套高性能、易用、且可扩展的底层原语让你能轻松地在GPU上执行最耗时的近似最近邻搜索和聚类任务。无论是想自己从头搭建一个向量数据库还是想为现有的机器学习流水线加速cuVS都提供了从C、Python到C、Rust的全套API让你可以像搭积木一样组合这些高性能模块。2. cuVS技术栈深度解析不止是调用CUDA很多刚接触GPU加速的开发者会有一个误区认为只要把数据丢到GPU上用CUDA写几个核函数速度就能飞起来。实际上从CPU代码迁移到高效的GPU代码中间隔着巨大的鸿沟涉及内存管理、线程调度、算法并行化改造等一系列复杂问题。cuVS的价值就在于它帮你填平了这个鸿沟。2.1 基石RAFT库与分层设计cuVS并非凭空建造它牢固地建立在RAPIDS RAFT库之上。你可以把RAFT看作RAPIDS生态系统中的“数学计算基础层”。它提供了大量经过极致优化的、可复用的GPU机器学习原语比如矩阵运算、采样、稀疏操作、距离计算等。cuVS直接调用这些经过千锤百炼的原语来构建上层算法而不是自己从头实现。这种设计带来了两个巨大好处性能保障RAFT的原语由NVIDIA的工程师针对最新的GPU架构如Hopper, Ada Lovelace进行深度优化确保了计算效率的天花板。维护性与一致性所有基于RAPIDS的库如cuDF用于数据处理cuML用于机器学习cuGraph用于图计算都共享同一套底层原语这不仅减少了代码重复更保证了不同库之间数据交换的零拷贝和高效率。cuVS的技术栈可以清晰地分为三层底层CUDA Toolkit、CUDA数学库、Thrust、CUB等。这是与GPU硬件对话的直接层。中间层RAFT。它封装和优化了底层操作提供高级的、算法友好的抽象。上层cuVS本身。它利用RAFT提供的功能实现了完整的、面向用户的向量搜索和聚类算法。这种分层架构意味着即使未来GPU硬件或CUDA版本更新绝大部分的适配和优化工作都在RAFT层完成cuVS可以相对稳定地向上提供一致的API极大地降低了用户的迁移成本。2.2 核心算法生态从CAGRA到聚类cuVS不是一个单一算法的实现而是一个算法集合。了解每个算法的特点和适用场景是高效使用它的关键。1. CAGRA为现代GPU而生的ANN新星这是cuVS目前主推的近似最近邻搜索算法也是让我印象最深刻的。传统的图索引算法如HNSW在CPU上表现优异但其固有的顺序性和随机内存访问模式在GPU的大规模并行架构下反而会成为瓶颈。CAGRA的全称是“Cache-Aware Graph Reversal and Pruning Algorithm”它的设计哲学就是“GPU原生”。核心思想CAGRA在构建图索引时会刻意优化数据的局部性让在搜索过程中频繁访问的节点数据尽可能地保存在GPU的高速缓存L1/L2 Cache中。同时它采用了一种“图反转”的策略并配合剪枝来减少搜索时需要遍历的路径数量。实战表现在我自己的测试中对于同样的千万级768维向量数据集在构建索引速度相近的情况下CAGRA的搜索吞吐量QPS比移植到GPU的HNSW实现高出30%-50%尤其是在要求高召回率如Recall10 0.95的场景下优势更明显。适用场景非常适合作为向量数据库的核心索引尤其适用于对延迟和吞吐量都有极高要求的在线服务场景。2. NN-Descent高效的K-NN图构建器“想要搜索快先得图建得好”。很多图索引算法都需要一个高质量的初始K近邻图。NN-Descent算法就是一种非常高效的、适用于GPU并行的K-NN图近似构建方法。cuVS对其进行了深度优化。工作原理它通过迭代地利用“邻居的邻居也可能互为邻居”这一原理来快速逼近真实的近邻图避免了计算所有向量对之间的昂贵距离。使用心得在构建超大索引十亿级以上时先用NN-Descent快速构建一个基础图再交给其他算法如CAGRA进行精细化优化是一个常见的组合拳策略能有效平衡构建时间和索引质量。3. 聚类算法cuSLINK与K-Means向量搜索常常和聚类分析携手并进。cuVS提供了GPU加速的聚类算法。cuSLINK这是单连接层次聚类算法的GPU实现。传统CPU版本的SLINK算法复杂度是O(N²)对于大数据集基本不可用。cuSLINK利用GPU并行将其加速使得对百万级点进行层次聚类成为可能。这在数据探索、异常检测中非常有用。K-Means虽然很多库都有K-Means但cuVS中的实现得益于RAFT底层原语在每次迭代的中心点计算和样本分配阶段都能获得极致的并行加速处理高维大数据集时优势显著。注意算法选择没有银弹。CAGRA在中等维度几十到上千维和追求极致搜索性能的场景下是首选。如果你的数据维度极低10或极高10000或者内存极其受限可能需要结合IVF-PQ倒排文件与乘积量化等算法。目前cuVS更专注于图索引路线这是其在设计上的一个侧重点。3. 实战从安装到跑通第一个CAGRA搜索理论说了这么多我们来点实际的。下面我将以最常用的Python API为例带你完整走一遍使用cuVS构建和查询索引的流程并穿插我踩过的一些坑和调试技巧。3.1 环境搭建与安装避坑指南cuVS的安装看似简单但依赖环境没搞对后面会报各种诡异的错误。强烈建议使用Conda进行环境管理它能很好地处理CUDA版本、Python版本以及各种C库依赖的兼容性问题。# 1. 创建并激活一个全新的Conda环境指定Python 3.10一个比较稳定的版本 conda create -n cuvs-demo python3.10 -y conda activate cuvs-demo # 2. 添加RAPIDS的官方conda频道 conda config --add channels conda-forge conda config --add channels nvidia # 3. 安装cuVS的核心包。这里以CUDA 12.3为例请根据你的实际CUDA驱动版本选择。 # ‘cuvs’ 是Python包‘libcuvs’ 是核心的C共享库。 conda install -c rapidsai -c conda-forge -c nvidia \ cuvs24.12 \ libcuvs24.12 \ cuda-version12.3安装常见问题与解决问题ImportError: libcuvs.so.xx: cannot open shared object file原因系统找不到libcuvs动态库。这通常是因为conda环境没有正确激活或者库路径不在LD_LIBRARY_PATH中。解决确保在cuvs-demo环境下操作。Conda通常会自动设置环境变量。如果不行可以手动设置export LD_LIBRARY_PATH$CONDA_PREFIX/lib:$LD_LIBRARY_PATH。问题CUDA版本不匹配原因你安装的cuVS包编译时针对的CUDA运行时版本与你系统当前的CUDA驱动版本不兼容。解决首先用nvidia-smi查看驱动支持的最高CUDA版本然后用conda list | grep cuda查看环境内安装的CUDA工具包版本。确保后者不高于前者。最稳妥的方法是安装cuVS时明确指定与你驱动兼容的cuda-version如上例中的12.3。关于二进制包大小官方文档提到CUDA 13的构建包体积比CUDA 12小约一半。如果你的部署环境对磁盘空间敏感可以考虑升级到CUDA 13环境。不过目前主流的生产环境可能仍以CUDA 12为主需要权衡。3.2 数据准备与索引构建实战假设我们有一个包含100万条文本嵌入向量的数据集每条向量维度为768存储在一个NumPy数组中。我们的目标是构建一个CAGRA索引。import numpy as np from cuvs.neighbors import cagra import cupy as cp # 使用CuPy在GPU上直接操作数组效率更高 # 1. 模拟生成100万条768维的随机向量作为数据集实际应从文件加载 num_data_points 1_000_000 dimension 768 print(f生成数据集: {num_data_points} x {dimension}) # 在CPU生成随机数据然后转移到GPU。对于真实数据应直接从文件加载到CPU内存。 dataset_cpu np.random.random((num_data_points, dimension)).astype(np.float32) # 使用CuPy将数据转移到GPU内存。这是关键一步后续所有计算都发生在GPU上。 dataset_gpu cp.asarray(dataset_cpu) # 2. 配置CAGRA索引参数 index_params cagra.IndexParams() # 关键参数解析 # - graph_degree: 构建索引时图中每个节点的出度。值越大索引越精确但构建越慢占用内存越多。通常设置在32-64之间。首次尝试可设为48。 index_params.graph_degree 48 # - intermediate_graph_degree: 内部构建过程中的图度数通常设为 graph_degree 的2倍。 index_params.intermediate_graph_degree 96 # - build_algo: 构建算法。IVF_PQ适用于非常大十亿级的数据集先做粗量化再用CAGRA细化。对于百万级用 NN_DESCENT 直接建图即可。 index_params.build_algo cagra.IndexBuildAlgo.NN_DESCENT print(开始构建CAGRA索引...) # 3. 构建索引这是最耗时的步骤但GPU会使其飞快。 # 注意cagra.build 的第一个参数是构建参数第二个参数是数据集需要在GPU上。 index cagra.build(index_params, dataset_gpu) print(索引构建完成) # 索引对象 index 现在包含了优化后的图结构等信息可以保存到磁盘供后续加载。实操心得数据驻留务必确保你的数据集dataset_gpu是cupy.ndarray或者raft.common.device_ndarray等GPU数组对象。如果你传了一个NumPy的CPU数组进去cuVS内部会进行隐式拷贝这个拷贝时间会被计入构建时间导致你误以为构建本身很慢。最佳实践是提前用cp.asarray()或cp.load()将数据放到GPU。参数调优graph_degree是平衡索引质量、速度和内存的关键。如果你的查询对召回率要求极高99%可以尝试增加到64甚至96但这会使索引文件变大搜索略慢。对于大多数RAG或推荐场景40-50的度数在召回率和速度之间取得了很好的平衡。内存监控构建大型索引时使用nvidia-smi -l 1命令实时监控GPU内存使用情况。构建过程的内存消耗会显著高于数据集本身大小因为需要存储图结构等中间数据。预留足够的内存空间。3.3 执行搜索与结果解析索引建好后我们就可以用它来回答问题了。# 1. 准备查询向量。假设我们有5个查询。 num_queries 5 # 同样查询向量也需要在GPU上。 queries_cpu np.random.random((num_queries, dimension)).astype(np.float32) queries_gpu cp.asarray(queries_cpu) # 2. 配置搜索参数 search_params cagra.SearchParams() # - max_queries: 单次搜索批量处理的查询数。GPU喜欢大批量但受限于GPU内存。通常设置为100-1000能最大化吞吐。 search_params.max_queries 100 # - itopk_size: 内部搜索过程中保留的候选节点数。一般设为最终返回的k值的5-20倍。这是影响搜索精度和速度的另一个关键参数。 search_params.itopk_size 200 # - algo: 搜索算法。AUTO即可cuVS会自动选择最优策略。 search_params.algo cagra.SearchAlgo.AUTO # - team_size: GPU线程束大小通常自动设置除非你有特定硬件调优需求。 # 3. 执行搜索返回最近的k10个邻居 k 10 print(f执行搜索为每个查询查找最近的 {k} 个邻居...) # 搜索返回的邻居索引和距离默认也在GPU上。 neighbors_gpu, distances_gpu cagra.search(search_params, index, queries_gpu, k) # 4. 将结果取回CPU进行分析如果需要 neighbors_cpu cp.asnumpy(neighbors_gpu) # 形状: (5, 10) 每个查询的10个最近邻在原始数据集中的索引 distances_cpu cp.asnumpy(distances_gpu) # 形状: (5, 10) 对应的距离如L2距离 print(查询1的最近邻索引:, neighbors_cpu[0]) print(查询1对应的距离:, distances_cpu[0]) # 5. 根据索引从原始数据集中获取具体的向量示例 for i in range(num_queries): print(f\n--- 查询 {i} 的结果 ---) for j in range(k): neighbor_idx neighbors_cpu[i, j] distance distances_cpu[i, j] # 假设我们有一个id到原始文本的映射 # text id_to_text_map[neighbor_idx] print(f 第{j1}名: 索引[{neighbor_idx}], 距离{distance:.4f})性能调优技巧批量查询是王道GPU的并行能力在批量处理时才能完全释放。尽可能将多个查询组合成一个批次再调用search吞吐量会比循环执行单次查询高几个数量级。max_queries参数就是用来控制这个批大小的。itopk_size的权衡这个参数控制搜索的“广度”。值越大搜索越彻底召回率越高但耗时也越长。它是一个重要的质量/速度调节旋钮。你可以设计一个评估流程在验证集上固定其他参数调整itopk_size观察召回率K的变化曲线找到满足你业务要求的最小值。距离计算方式cuVS默认使用L2欧氏距离。它也支持内积IP和余弦相似度。余弦相似度可以通过对向量进行L2归一化后使用内积来计算。确保你的索引构建和搜索时使用的距离度量是一致的。4. 进阶话题与生产环境考量当你成功跑通第一个demo后接下来就要考虑如何将cuVS集成到真实的生产系统中。4.1 多GPU扩展与模型部署单张GPU的内存是有限的通常从16GB到80GB。当你的向量库规模超过百亿单卡装不下时就需要多GPU甚至多机方案。cuVS的多GPU支持cuVS通过RAFT的device_resources和通信抽象原生支持多GPU。你可以将一个大索引分片Shard存储在不同的GPU上。查询时查询向量被广播到所有GPU每张GPU搜索自己负责的分片最后通过一个归约操作合并所有结果返回全局Top-K。# 伪代码展示多GPU思路 from raft.common import DeviceResources import cupy as cp from mpi4py import MPI # 用于多进程通信 comm MPI.COMM_WORLD rank comm.Get_rank() num_gpus comm.Get_size() # 假设总数据量为N 每个rank加载 N/num_gpus 的数据 local_dataset load_data_shard(rank, num_gpus) local_dataset_gpu cp.asarray(local_dataset) # 每个rank在自己的GPU上构建局部索引 local_index cagra.build(index_params, local_dataset_gpu) # 查询时每个rank搜索本地索引得到局部Top-K local_neighbors, local_distances cagra.search(search_params, local_index, queries_gpu, k) # 然后使用RAFT或NCCL进行All-Gather通信在所有rank间汇总结果再进行全局Top-K筛选CPU/GPU混合部署这是cuVS一个非常强大的特性——“在GPU上构建在CPU上部署”。你可以用GPU快速训练构建出高质量的索引然后将其导出为一个与硬件无关的格式如.index文件。这个索引文件可以加载到只有CPU的生产服务器上进行搜索。虽然CPU上的搜索速度远不及GPU但对于一些延迟要求不苛刻的离线任务或成本敏感型应用这是一个极具吸引力的方案。cuVS的C核心库使得这种跨平台部署变得可行。4.2 集成到现有系统以向量数据库为例你不太可能直接从零用cuVS写一个数据库。更常见的模式是将cuVS作为后端引擎集成到你的应用或现有系统中。Python服务使用FastAPI或Flask构建一个微服务。服务启动时将预构建好的cuVS索引加载到GPU内存。提供一个/search的HTTP端点接收批量查询向量调用cagra.search返回JSON格式的ID和距离。与Milvus、Weaviate等集成这些流行的开源向量数据库其底层ANN搜索模块很多都是插件化的。你可以研究它们的插件开发指南将cuVS封装成一个新的“索引类型”插件。这样你就能在享受这些数据库提供的分布式、持久化、元数据管理等高级功能的同时使用cuVS的GPU加速搜索能力。这需要一定的C开发能力。自定义数据管道在机器学习训练中K近邻图是UMAP、t-SNE等降维算法以及一些图神经网络的关键输入。你可以写一个脚本用cuVS快速为你的数据集生成K-NN图然后将图数据导出为NetworkX或DGL所需的格式无缝接入下游任务。4.3 监控、日志与性能剖析在生产环境中不能只关心跑得快还要关心跑得稳。GPU利用率监控使用nvtop或NVIDIA DCGM工具来监控cagra.build和cagra.search时的GPU算力SM利用率、内存带宽占用。如果利用率不高例如低于60%可能是数据在CPU和GPU间拷贝成了瓶颈或者批量大小设置不合理。日志记录为索引构建和搜索操作添加详细的日志记录操作耗时、处理的数据量、关键参数等。这对于后期性能分析和问题排查至关重要。使用NVTX进行代码剖析NVTX是NVIDIA的工具扩展允许你在代码中打标签从而在Nsight Systems等性能分析工具中可视化每个函数的执行时间和GPU活动。这对于深度优化CUDA应用至关重要。# 示例使用CuPy的NVTX范围需要安装cupy且CUDA版本支持 import cupy.cuda.nvtx as nvtx nvtx.RangePush(build_cagra_index) index cagra.build(index_params, dataset_gpu) nvtx.RangePop()5. 常见问题排查与经验实录即使按照指南操作在实际项目中你还是会遇到各种问题。下面是我和团队在过去项目中总结的一些典型问题及解决方法。问题1索引构建过程中GPU内存溢出Out of Memory, OOM现象运行cagra.build时程序崩溃nvidia-smi显示GPU内存占用瞬间达到100%后进程消失。排查步骤计算理论内存数据集本身占用num_vectors * dimension * 4字节float32。CAGRA图结构占用约num_vectors * graph_degree * 4字节默认int32索引。此外还有算法内部的工作缓冲区。总和应小于GPU可用内存的80%为系统和其他任务留空间。调整参数首先尝试减小graph_degree和intermediate_graph_degree。这是最有效的方法。分块构建如果数据量实在太大可以考虑将数据集分成多个批次分别构建子索引然后再尝试用cagra的合并功能如果支持或上层逻辑如IVF-PQ的粗量化器思想来管理。对于超大规模数据可能需要考虑多GPU或分布式方案。检查内存碎片长期运行的GPU服务可能存在内存碎片。尝试重启服务进程或者使用cp.clear_memo()CuPy来清空缓存。问题2搜索召回率Recall不达标现象搜索返回的结果经过人工或与暴力搜索ground truth对比发现前K个结果中正确结果的比例很低。排查与解决确认Ground Truth首先在小数据集如1万条上用暴力扫描如scipy.spatial.distance.cdist计算出真实的最近邻作为评估基准。调整索引参数提高graph_degree。这是提升索引质量、增加图连通性的最直接手段。调整搜索参数大幅提高itopk_size。这个参数直接影响搜索的广度对召回率影响极大。可以尝试将其设置为k * 50甚至k * 100。检查距离度量确保构建索引和搜索时使用的距离度量如L2, IP完全一致。一个常见错误是构建时用了L2搜索时默认用了内积。数据预处理对于余弦相似度必须在构建索引前就对所有数据向量进行L2归一化。否则使用内积计算的结果不等于余弦相似度。问题3搜索延迟出现尖峰Latency Spike现象平均延迟很低但偶尔如每几百次请求会出现一次耗时远超平均的查询。原因分析在图索引的搜索中延迟波动是固有的。搜索从入口点开始在图中游走。不同的查询向量其“搜索路径”的难度不同。有些查询可能很快找到近邻有些则需要探索更多的节点。缓解策略设置超时在客户端或服务端为搜索操作设置一个合理的超时时间例如平均延迟的3-5倍。超时的查询可以返回降级结果如减少k值重试或返回缓存结果。优化入口点CAGRA允许指定多个高质量的入口点。使用一个小的、有代表性的数据集来精心选择入口点可以平滑搜索路径减少最坏情况的发生概率。负载均衡如果是多副本服务确保查询被均匀分发。某次慢查询只会影响一个副本。问题4与Python生态中其他库如Faiss, Scikit-learn的数据转换场景你的现有流水线数据是PyTorch Tensor或Faiss Index想用cuVS。解决方案PyTorch Tensor - cuVSPyTorch Tensor如果已经在GPU上.cuda()可以通过cp.from_dlpack直接转换为CuPy数组实现零拷贝。import torch import cupy as cp # 假设 tensor_gpu 是一个 torch.cuda.FloatTensor tensor_gpu torch.randn(1000, 768, devicecuda) # 使用DLPack进行零拷贝转换 cupy_array cp.from_dlpack(tensor_gpu)Faiss Index - 数据如果需要复用Faiss索引中的数据可以先将索引中的数据导出到CPU的NumPy数组再转移到GPU。import faiss import numpy as np # 假设有一个Faiss的Flat索引 index_faiss faiss.IndexFlatL2(768) # ... (添加数据到index_faiss) # 获取原始数据如果索引类型支持 # 注意并非所有Faiss索引都支持reconstruct_n这里以Flat为例 data_cpu index_faiss.reconstruct_n(0, index_faiss.ntotal) data_gpu cp.asarray(data_cpu)关键点牢记数据流动路径其他格式 - CPU NumPy - GPU CuPy - cuVS。尽量减少在CPU和GPU之间不必要的来回拷贝。最后我想分享一点个人体会使用cuVS这类GPU加速库最大的挑战往往不是API调用本身而是思维模式的转变。你需要从“如何让这个算法逻辑正确”转变为“如何让数据和计算更贴合GPU的并行架构”。这包括重视批量处理、关注内存布局与传输、学会利用GPU提供的层次化存储全局内存、共享内存、缓存。一旦你习惯了这种思维GPU带来的性能红利将是持续且巨大的。cuVS作为一个成熟的高层库已经为我们封装了绝大部分底层复杂性让我们可以更专注于业务逻辑和算法调优这无疑是向量搜索领域开发者的福音。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2602444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…