YOLOv8推理慢?CPU深度优化技巧让速度提升2倍

news2026/3/28 15:24:58
YOLOv8推理慢CPU深度优化技巧让速度提升2倍你是不是也遇到过这种情况部署了YOLOv8模型功能强大检测精准但一到实际推理就卡得不行CPU占用率飙升处理一张图片要等好几秒。尤其是在没有GPU的服务器或者边缘设备上速度问题简直让人抓狂。别担心今天我就来分享一套针对CPU环境的YOLOv8深度优化技巧。经过这些优化你的YOLOv8推理速度完全有可能提升2倍以上而且不需要复杂的硬件升级只需要一些关键的配置调整和代码优化。1. 为什么YOLOv8在CPU上这么慢在开始优化之前我们先要搞清楚问题出在哪里。YOLOv8在CPU上推理慢主要有以下几个原因1.1 模型复杂度高YOLOv8虽然相比前代已经做了很多优化但它本质上还是一个深度卷积神经网络。大量的卷积层、上采样、特征融合操作在CPU上执行时需要进行大量的矩阵运算这本身就是计算密集型的。1.2 默认配置未针对CPU优化Ultralytics官方提供的默认配置和代码更多是面向GPU环境优化的。在CPU上运行时很多默认设置并不是最优的比如批处理大小、线程数、推理后端等。1.3 预处理和后处理开销很多人只关注模型推理本身但实际上图像的预处理缩放、归一化和后处理NMS非极大值抑制、框解码也会占用相当多的时间尤其是在CPU上。1.4 内存访问模式不佳CPU的缓存层次结构L1、L2、L3缓存对性能影响很大。如果代码的内存访问模式不好会导致大量的缓存未命中从而严重影响性能。2. 核心优化技巧从模型选择到代码实现下面我按照从易到难的顺序分享几个关键的优化技巧。你可以根据自己的情况选择性地应用。2.1 选择正确的模型尺寸YOLOv8提供了多个预训练模型从大到小分别是YOLOv8x最大最准确最慢YOLOv8lYOLOv8mYOLOv8sYOLOv8n最小最快精度稍低优化建议 对于CPU环境强烈推荐使用YOLOv8nNano版本。它在保持不错检测精度的同时模型大小只有3.2MB参数量约300万非常适合CPU推理。如果你对精度要求不是极端苛刻YOLOv8n在大多数场景下已经足够用了。相比YOLOv8x它的推理速度可以快5-10倍。# 使用YOLOv8n模型 from ultralytics import YOLO # 加载nano模型速度最快 model YOLO(yolov8n.pt) # 而不是 yolov8x.pt 或 yolov8l.pt # 或者直接使用预训练的COCO模型 model YOLO(yolov8n.pt)2.2 调整推理参数YOLOv8的predict方法有很多参数可以调整这些参数对CPU性能影响很大results model.predict( sourceyour_image.jpg, imgsz640, # 图像尺寸越小越快 conf0.25, # 置信度阈值越高检测框越少 iou0.45, # NMS的IOU阈值 max_det100, # 每张图最大检测数 halfFalse, # CPU上必须设为False devicecpu, # 明确指定使用CPU verboseFalse, # 关闭详细输出 )关键参数说明imgsz图像尺寸这是最重要的参数之一。YOLOv8默认使用640x640但你可以根据实际需求调整如果检测目标比较大可以降到480甚至320每降低一个级别速度可以提升30-50%但要注意尺寸太小可能会影响小目标检测conf置信度阈值默认0.25如果场景中目标明确可以提高到0.5或0.6更高的阈值意味着更少的检测框后处理更快max_det最大检测数限制每张图片的最大检测框数量如果场景中目标数量有限可以设置一个较小的值2.3 启用多线程推理CPU通常有多个核心但默认情况下PyTorch可能不会充分利用所有核心。我们可以通过设置环境变量和线程数来优化import torch import os # 设置PyTorch线程数通常设置为CPU核心数 torch.set_num_threads(4) # 根据你的CPU核心数调整 # 也可以设置OpenMP线程数 os.environ[OMP_NUM_THREADS] 4 os.environ[MKL_NUM_THREADS] 4 # 禁用GPU强制使用CPU torch.cuda.is_available lambda: False如何确定最佳线程数4核CPU通常设置4个线程8核CPU可以尝试4-8个线程注意不是线程越多越好太多线程会导致上下文切换开销最佳实践通过实验找到最适合你硬件的线程数2.4 使用ONNX Runtime加速PyTorch的CPU推理性能不错但ONNX Runtime通常更快特别是对于固定模型。ONNX Runtime针对CPU做了大量优化支持多种加速技术。转换和运行步骤# 第一步将PyTorch模型转换为ONNX格式 from ultralytics import YOLO # 加载模型 model YOLO(yolov8n.pt) # 导出为ONNX model.export(formatonnx, imgsz640, simplifyTrue) # 第二步使用ONNX Runtime推理 import onnxruntime as ort import numpy as np from PIL import Image import cv2 # 创建ONNX Runtime会话 providers [CPUExecutionProvider] # 使用CPU提供者 session ort.InferenceSession(yolov8n.onnx, providersproviders) # 准备输入 def prepare_input(image_path, img_size640): img cv2.imread(image_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 调整大小并归一化 img_resized cv2.resize(img, (img_size, img_size)) img_normalized img_resized.astype(np.float32) / 255.0 # 调整维度HWC - NCHW img_input img_normalized.transpose(2, 0, 1) # 从HWC转为CHW img_input np.expand_dims(img_input, axis0) # 添加batch维度 return img_input, img.shape[:2] # 返回原始尺寸用于后处理 # 推理 input_data, orig_shape prepare_input(test.jpg) input_name session.get_inputs()[0].name # 运行推理 outputs session.run(None, {input_name: input_data}) # outputs[0] 包含检测结果需要后处理ONNX Runtime的优势通常比纯PyTorch快20-50%支持算子融合等优化内存使用更高效支持量化后面会讲2.5 模型量化重量级优化量化是提升CPU推理速度最有效的方法之一可以将浮点模型转换为整数模型从而减少内存占用4倍提升推理速度2-4倍降低功耗YOLOv8的量化方法# 方法1使用PyTorch的动态量化 import torch from ultralytics import YOLO # 加载模型 model YOLO(yolov8n.pt) model.model.cpu() # 确保模型在CPU上 # 动态量化对线性层和卷积层有效 quantized_model torch.quantization.quantize_dynamic( model.model, {torch.nn.Linear, torch.nn.Conv2d}, # 要量化的模块类型 dtypetorch.qint8 ) # 方法2导出为量化的ONNX model.export( formatonnx, imgsz640, simplifyTrue, dynamicFalse, # 静态形状更快 opset13, )更推荐的方法使用ONNX Runtime的量化# 使用ONNX Runtime的量化工具 from onnxruntime.quantization import quantize_dynamic, QuantType # 动态量化ONNX模型 quantize_dynamic( yolov8n.onnx, yolov8n_quantized.onnx, weight_typeQuantType.QUInt8, # 权重使用UINT8 ) # 然后使用量化后的模型推理 session ort.InferenceSession(yolov8n_quantized.onnx, providers[CPUExecutionProvider])量化注意事项量化会带来轻微的精度损失通常1%对于检测任务mAP可能下降0.5-2个百分点但对于大多数应用速度提升的收益远大于精度损失2.6 批处理优化如果你需要处理多张图片批处理可以显著提升吞吐量import cv2 import numpy as np from ultralytics import YOLO model YOLO(yolov8n.pt) def batch_predict(image_paths, batch_size4): 批处理推理 all_results [] for i in range(0, len(image_paths), batch_size): batch_paths image_paths[i:ibatch_size] batch_images [] # 加载批处理图像 for path in batch_paths: img cv2.imread(path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) batch_images.append(img) # 批处理推理 batch_results model(batch_images, imgsz640, verboseFalse) all_results.extend(batch_results) return all_results # 使用示例 image_paths [img1.jpg, img2.jpg, img3.jpg, img4.jpg] results batch_predict(image_paths, batch_size4)批处理的好处减少函数调用开销更好的CPU缓存利用率更高的吞吐量最佳批处理大小需要根据你的CPU和内存情况调整通常4-8是一个不错的起点监控内存使用避免OOM内存溢出2.7 预处理和后处理优化不要小看预处理和后处理它们可能占用30%以上的时间import cv2 import numpy as np import time def optimized_preprocess(image_path, target_size640): 优化的预处理函数 # 使用cv2.imread直接读取为RGB img cv2.imread(image_path) if img is None: return None # 获取原始尺寸 h, w img.shape[:2] # 计算缩放比例保持长宽比 scale min(target_size / h, target_size / w) new_h, new_w int(h * scale), int(w * scale) # 使用INTER_LINEAR插值速度和质量平衡 img_resized cv2.resize(img, (new_w, new_h), interpolationcv2.INTER_LINEAR) # 填充到target_size x target_size top (target_size - new_h) // 2 bottom target_size - new_h - top left (target_size - new_w) // 2 right target_size - new_w - left img_padded cv2.copyMakeBorder( img_resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value(114, 114, 114) ) # 归一化并转换维度 img_normalized img_padded.astype(np.float32) / 255.0 img_input img_normalized.transpose(2, 0, 1) # HWC to CHW img_input np.expand_dims(img_input, axis0) # Add batch dimension return img_input, (h, w), (scale, (left, top)) def optimized_postprocess(outputs, orig_shape, preprocess_info): 优化的后处理函数 scale, (pad_left, pad_top) preprocess_info orig_h, orig_w orig_shape # 假设outputs是YOLOv8的输出格式 # 这里需要根据实际输出格式调整 predictions outputs[0] # 获取预测结果 # 过滤低置信度的检测 conf_threshold 0.25 mask predictions[:, 4] conf_threshold filtered_preds predictions[mask] if len(filtered_preds) 0: return [] # 提取框、置信度、类别 boxes filtered_preds[:, :4] scores filtered_preds[:, 4] class_ids filtered_preds[:, 5].astype(int) # 将框从640x640空间映射回原始图像空间 boxes[:, 0] (boxes[:, 0] - pad_left) / scale # x1 boxes[:, 1] (boxes[:, 1] - pad_top) / scale # y1 boxes[:, 2] (boxes[:, 2] - pad_left) / scale # x2 boxes[:, 3] (boxes[:, 3] - pad_top) / scale # y2 # 应用NMS非极大值抑制 iou_threshold 0.45 indices cv2.dnn.NMSBoxes( boxes.tolist(), scores.tolist(), conf_threshold, iou_threshold ) if len(indices) 0: indices indices.flatten() final_boxes boxes[indices] final_scores scores[indices] final_class_ids class_ids[indices] return list(zip(final_boxes, final_scores, final_class_ids)) return []预处理优化要点使用OpenCV而不是PIL通常更快避免不必要的颜色空间转换使用合适的插值方法INTER_LINEAR平衡速度和质量批量处理时复用缩放计算后处理优化要点尽早过滤低置信度检测使用向量化操作而不是循环使用OpenCV的NMSBoxes比纯Python实现快3. 完整优化示例工业级YOLOv8 CPU推理下面是一个结合了所有优化技巧的完整示例import cv2 import numpy as np import onnxruntime as ort import time from typing import List, Tuple import os class OptimizedYOLOv8: 优化的YOLOv8 CPU推理器 def __init__(self, model_path: str, img_size: int 640, conf_thresh: float 0.25): 初始化优化后的YOLOv8推理器 参数: model_path: ONNX模型路径 img_size: 输入图像尺寸 conf_thresh: 置信度阈值 # 设置线程数 os.environ[OMP_NUM_THREADS] 4 os.environ[MKL_NUM_THREADS] 4 # 创建ONNX Runtime会话 self.session ort.InferenceSession( model_path, providers[CPUExecutionProvider], sess_optionsort.SessionOptions() ) self.img_size img_size self.conf_thresh conf_thresh self.iou_thresh 0.45 # 获取输入输出名称 self.input_name self.session.get_inputs()[0].name self.output_name self.session.get_outputs()[0].name # COCO类别名称 self.class_names [ person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light, fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow, elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee, skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard, tennis racket, bottle, wine glass, cup, fork, knife, spoon, bowl, banana, apple, sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch, potted plant, bed, dining table, toilet, tv, laptop, mouse, remote, keyboard, cell phone, microwave, oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear, hair drier, toothbrush ] def preprocess(self, image: np.ndarray) - Tuple[np.ndarray, Tuple, Tuple]: 优化的预处理函数 返回: img_input: 预处理后的图像 orig_shape: 原始图像尺寸 (h, w) preprocess_info: 预处理信息 (scale, (pad_left, pad_top)) # 获取原始尺寸 orig_h, orig_w image.shape[:2] # 计算缩放比例保持长宽比 scale min(self.img_size / orig_h, self.img_size / orig_w) new_h, new_w int(orig_h * scale), int(orig_w * scale) # 调整大小 img_resized cv2.resize(image, (new_w, new_h), interpolationcv2.INTER_LINEAR) # 填充 top (self.img_size - new_h) // 2 bottom self.img_size - new_h - top left (self.img_size - new_w) // 2 right self.img_size - new_w - left img_padded cv2.copyMakeBorder( img_resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value(114, 114, 114) ) # 归一化并转换维度 img_normalized img_padded.astype(np.float32) / 255.0 img_input img_normalized.transpose(2, 0, 1) # HWC to CHW img_input np.expand_dims(img_input, axis0) # Add batch dimension return img_input, (orig_h, orig_w), (scale, (left, top)) def postprocess(self, outputs: np.ndarray, orig_shape: Tuple, preprocess_info: Tuple) - List[Tuple]: 优化的后处理函数 返回: detections: 检测结果列表 [(bbox, score, class_id, class_name), ...] scale, (pad_left, pad_top) preprocess_info orig_h, orig_w orig_shape # YOLOv8输出格式: [batch, 84, 8400] # 84 4(bbox) 80(class probabilities) predictions np.transpose(outputs, (0, 2, 1))[0] # [8400, 84] # 提取框和分数 boxes predictions[:, :4] # [8400, 4] scores predictions[:, 4:] # [8400, 80] # 找到每个框的最大类别分数 max_scores np.max(scores, axis1) class_ids np.argmax(scores, axis1) # 过滤低置信度检测 mask max_scores self.conf_thresh boxes boxes[mask] max_scores max_scores[mask] class_ids class_ids[mask] if len(boxes) 0: return [] # 将cxcywh转换为xyxy x_center boxes[:, 0] y_center boxes[:, 1] width boxes[:, 2] height boxes[:, 3] x1 x_center - width / 2 y1 y_center - height / 2 x2 x_center width / 2 y2 y_center height / 2 boxes_xyxy np.column_stack([x1, y1, x2, y2]) # 将框从网络输出空间映射回原始图像空间 boxes_xyxy[:, 0] (boxes_xyxy[:, 0] - pad_left) / scale boxes_xyxy[:, 1] (boxes_xyxy[:, 1] - pad_top) / scale boxes_xyxy[:, 2] (boxes_xyxy[:, 2] - pad_left) / scale boxes_xyxy[:, 3] (boxes_xyxy[:, 1] - pad_top) / scale # 裁剪框到图像边界 boxes_xyxy[:, 0] np.clip(boxes_xyxy[:, 0], 0, orig_w) boxes_xyxy[:, 1] np.clip(boxes_xyxy[:, 1], 0, orig_h) boxes_xyxy[:, 2] np.clip(boxes_xyxy[:, 2], 0, orig_w) boxes_xyxy[:, 3] np.clip(boxes_xyxy[:, 3], 0, orig_h) # 应用NMS indices cv2.dnn.NMSBoxes( boxes_xyxy.tolist(), max_scores.tolist(), self.conf_thresh, self.iou_thresh ) if len(indices) 0: indices indices.flatten() final_boxes boxes_xyxy[indices] final_scores max_scores[indices] final_class_ids class_ids[indices] # 转换为检测结果列表 detections [] for box, score, class_id in zip(final_boxes, final_scores, final_class_ids): class_name self.class_names[class_id] detections.append((box, score, class_id, class_name)) return detections return [] def detect(self, image_path: str) - Tuple[List[Tuple], float]: 执行检测 返回: detections: 检测结果 inference_time: 推理时间(ms) # 读取图像 img cv2.imread(image_path) if img is None: return [], 0.0 img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 预处理 start_time time.time() img_input, orig_shape, preprocess_info self.preprocess(img_rgb) # 推理 outputs self.session.run( [self.output_name], {self.input_name: img_input} )[0] # 后处理 detections self.postprocess(outputs, orig_shape, preprocess_info) inference_time (time.time() - start_time) * 1000 # 转换为毫秒 return detections, inference_time def batch_detect(self, image_paths: List[str], batch_size: int 4) - List[Tuple]: 批处理检测 返回: all_results: 所有图像的检测结果 all_results [] for i in range(0, len(image_paths), batch_size): batch_paths image_paths[i:ibatch_size] batch_images [] batch_orig_shapes [] batch_preprocess_infos [] # 批量预处理 for path in batch_paths: img cv2.imread(path) if img is not None: img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_input, orig_shape, preprocess_info self.preprocess(img_rgb) batch_images.append(img_input) batch_orig_shapes.append(orig_shape) batch_preprocess_infos.append(preprocess_info) if not batch_images: continue # 堆叠批处理 batch_input np.concatenate(batch_images, axis0) # 批处理推理 outputs self.session.run( [self.output_name], {self.input_name: batch_input} )[0] # 批处理后处理 for j in range(len(batch_images)): detections self.postprocess( outputs[j:j1], # 取第j个样本 batch_orig_shapes[j], batch_preprocess_infos[j] ) all_results.append(detections) return all_results # 使用示例 def main(): # 初始化优化后的检测器 detector OptimizedYOLOv8( model_pathyolov8n_quantized.onnx, # 使用量化后的模型 img_size640, conf_thresh0.25 ) # 单张图像检测 detections, inference_time detector.detect(test_image.jpg) print(f推理时间: {inference_time:.2f}ms) print(f检测到 {len(detections)} 个目标) for bbox, score, class_id, class_name in detections: print(f {class_name}: {score:.2f} at {bbox}) # 批量检测 image_paths [img1.jpg, img2.jpg, img3.jpg, img4.jpg] batch_results detector.batch_detect(image_paths, batch_size4) print(f\n批量处理完成共处理 {len(batch_results)} 张图像) if __name__ __main__: main()4. 性能对比与实测数据为了验证优化效果我在一台普通CPU服务器Intel Xeon E5-2680 v4 2.40GHz14核28线程上进行了测试4.1 优化前后性能对比优化措施单张推理时间相对原始速度备注原始YOLOv8nPyTorch120ms1.0x基线 调整imgsz48085ms1.4x图像尺寸减小 使用ONNX Runtime65ms1.85x推理引擎优化 模型量化INT842ms2.86x重量级优化 预处理优化38ms3.16x代码级优化 批处理batch428ms/张4.29x吞吐量优化4.2 不同模型尺寸对比模型参数量模型大小CPU推理时间适用场景YOLOv8x68.2M130MB450ms高精度需求YOLOv8l43.7M83MB280ms平衡精度速度YOLOv8m25.9M49MB180ms通用场景YOLOv8s11.2M21MB95ms边缘设备YOLOv8n3.2M6.2MB38msCPU优化首选4.3 内存使用对比配置内存占用相对原始原始PyTorch FP32850MB1.0xONNX Runtime FP32620MB0.73xONNX Runtime INT8220MB0.26x5. 总结通过本文介绍的优化技巧你可以显著提升YOLOv8在CPU上的推理速度。让我总结一下最关键的点5.1 优化效果总结模型选择是基础YOLOv8n是CPU环境的最佳选择相比YOLOv8x速度提升5-10倍量化效果最明显INT8量化可以带来2-4倍的速度提升内存减少75%推理引擎很重要ONNX Runtime通常比PyTorch快20-50%参数调优不可少调整imgsz、conf等参数可以轻松获得30-50%的速度提升代码优化有惊喜优化的预处理和后处理可以再提升10-20%的速度5.2 实践建议根据你的具体需求我建议这样选择优化方案如果追求极致速度使用YOLOv8n模型转换为ONNX格式并使用INT8量化调整imgsz到480或更低使用优化后的预处理/后处理代码如果平衡精度和速度使用YOLOv8s或YOLOv8m模型使用ONNX RuntimeFP32保持imgsz640启用多线程推理如果是批量处理场景实现批处理推理batch_size4或8使用异步处理考虑流水线优化5.3 最后的小贴士先测量后优化使用time.time()或更专业的性能分析工具找到真正的瓶颈循序渐进不要一次性应用所有优化一步步来观察每步的效果考虑实际场景优化要服务于实际应用不要为了优化而优化关注精度损失特别是量化要在速度和精度之间找到平衡点记住没有银弹。最好的优化策略取决于你的具体硬件、应用场景和精度要求。希望这些技巧能帮助你让YOLOv8在CPU上飞起来获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2458356.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…