OpenHarness:多模态大模型应用开发的标准化框架与实战指南

news2026/4/30 9:52:50
1. 项目概述一个为多模态大模型打造的“万能工具箱”最近在折腾多模态大模型MMLM应用开发的朋友估计都遇到过类似的痛点想给模型加个视觉理解能力得自己写一堆预处理代码想处理个视频得找不同的库来抽帧、解析音频想把模型部署上线还得头疼服务化、并发和资源管理。这些繁琐的“脏活累活”占据了大量精力让我们离核心的创新应用越来越远。今天要聊的OpenHarness就是来解决这个问题的。简单来说它不是一个新模型而是一个专为多模态大模型应用开发设计的开源框架和工具集。你可以把它想象成一个高度模块化、可扩展的“万能工具箱”或者“乐高积木套装”。它的核心目标是把处理图像、视频、音频、文档等不同模态数据的通用能力以及模型推理、服务部署等工程环节抽象成标准化的组件。开发者无需重复造轮子只需像搭积木一样组合这些组件就能快速构建出功能强大、性能可靠的多模态应用。我第一次接触 OpenHarness 是在尝试为一个商品识别项目接入视觉大模型时。当时需要处理用户上传的图片进行尺寸归一化、格式转换、EXIF信息清除然后才能送入模型。这些代码写起来不难但琐碎且容易出错。OpenHarness 里现成的ImageLoader和ImageProcessor组件几行配置就搞定了而且内置了缓存、错误重试等生产级特性让我瞬间感觉找到了“神器”。它尤其适合以下几类朋友一是希望快速验证多模态应用创意的算法工程师和研究员二是需要将多模态能力稳定、高效集成到产品中的全栈或后端工程师三是从事AI应用开发希望提升团队协作效率和代码复用性的技术负责人。2. 核心设计理念标准化、可组合与生产就绪OpenHarness 的设计哲学非常清晰它不追求成为一个“大而全”的封闭系统而是致力于成为连接多模态数据与各类大模型的“粘合剂”和“加速器”。其架构设计紧密围绕三个核心原则展开。2.1 数据与处理的标准化抽象多模态开发的第一道坎就是数据异构性。一张JPG图片、一段MP4视频、一份PDF文档、一段WAV音频它们的存储格式、编码方式、元信息结构天差地别。OpenHarness 的第一步就是为这些不同模态的数据定义了一套统一的内部表示。它引入了Modality和DataItem的核心概念。无论输入是什么最终都会被封装成一个或多个标准化的DataItem。例如一个视频文件会被解构成一个包含多个图像帧视觉模态和一个音频波形听觉模态的DataItem列表。每个DataItem都带有清晰的元数据如来源、尺寸、采样率、时间戳等并且其底层数据像素数组、音频张量、文本token以一种高效、统一的方式在内存中管理。这种抽象带来的最大好处是下游组件无需关心数据来源。一个视觉特征提取器只需要声明它接受“图像”模态的DataItem那么无论是来自摄像头、本地文件还是网络URL的图片在经过前端的Loader加载器和Processor处理器转换后都能以同样的格式喂给它。这极大地降低了组件间的耦合度。2.2 流水线式的可组合执行在标准化数据表示的基础上OpenHarness 采用了Pipeline流水线作为核心的执行范式。一个完整的应用被建模为一条由多个Node节点构成的有向无环图DAG。每个Node都是一个功能独立的组件例如Loader: 负责从各种源文件系统、对象存储、数据库、URL加载原始数据。Processor: 负责数据的预处理如图像缩放、音频降噪、文本分词。Model: 封装了具体的多模态大模型如CLIP、BLIP、LLaVA等的推理逻辑。Aggregator: 对多个Model节点的输出进行聚合或决策。Writer: 将处理结果输出到指定目的地。开发者通过一个声明式的配置文件通常是YAML或Python API来定义这些节点的连接关系和数据流向。例如一个简单的“图片描述生成”流水线可能长这样FileLoader - ImageDecoder - NormalizeProcessor - CaptionModel - JsonWriter。这种设计让复杂应用的构建变得直观且灵活。如果你想增加一个“目标检测”的前置步骤只需在流水线中插入一个DetectionModel节点如果你想并行处理图片的不同区域可以配置分支流水线。所有节点的输入输出都基于标准的DataItem组合起来几乎没有任何障碍。2.3 面向生产环境的工程考量很多研究导向的工具在工程化时往往捉襟见肘而 OpenHarness 从设计之初就考虑了生产部署的需求。首先是性能。框架内部实现了异步I/O、操作符融合将多个简单的Processor合并为一个以减少数据拷贝、以及可配置的批处理Batching机制。对于模型推理节点它可以无缝集成像 vLLM、TensorRT-LLM 这样的高性能推理后端充分利用GPU资源。其次是可观测性。流水线中的每个节点都内置了指标收集功能如处理耗时、输入输出数据量、错误次数等。这些指标可以通过 Prometheus 等工具暴露方便进行监控和性能剖析。框架还提供了详细的日志和分布式追踪通过OpenTelemetry当流水线某个环节出现瓶颈或错误时可以快速定位问题根源。最后是部署灵活性。OpenHarness 应用可以以多种模式运行在开发阶段可以作为单个Python进程快速调试在生产环境可以借助其内置的适配器轻松部署为基于 HTTP/gRPC 的微服务或者打包成 Docker 镜像在 Kubernetes 上弹性伸缩。它甚至支持将流水线编译成更高性能的执行图以应对极致的延迟要求。3. 核心组件深度解析与实操要点理解了设计理念我们深入到 OpenHarness 的几个核心组件内部看看它们具体如何工作以及在实际使用中需要注意什么。3.1 数据加载器与处理器从原始数据到标准输入Loader和Processor是流水线的“左膀右臂”负责将杂乱无章的原始数据清洗、转换成模型期待的“美味佳肴”。1. Loader数据入口的多样性OpenHarness 提供了丰富的内置 LoaderFileSystemLoader: 从本地或网络挂载的磁盘读取文件。UrlLoader: 从HTTP/HTTPS链接下载数据支持设置超时、重试和请求头。S3Loader/AzureBlobLoader: 直接从云存储服务加载避免不必要的本地下载。DatabaseLoader: 从关系型或向量数据库中查询并加载数据。实操心得使用UrlLoader加载网络图片时务必设置合理的timeout和retry_times。网络环境不稳定是常态一个失败的请求不应该导致整个流水线崩溃。建议配合缓存使用对相同的URL在一定时间内直接返回缓存结果既能提升速度也能减少对目标服务器的压力。2. Processor数据清洗与增强的艺术Processor 的种类更多针对不同模态视觉类ResizeProcessor调整尺寸、CenterCropProcessor中心裁剪、NormalizeProcessor像素值归一化如从[0,255]到[0,1]或使用ImageNet均值和标准差。这里有一个关键细节不同的视觉模型预处理要求可能不同。例如CLIP 和 DINOv2 的归一化参数就不同。OpenHarness 的处理器通常允许通过配置指定这些参数。文本类TokenizerProcessor调用Hugging Face tokenizer、TextCleanProcessor去除多余空格、特殊字符。音频类ResampleProcessor重采样至统一频率、ToMonoProcessor立体声转单声道。# 示例一个针对CLIP模型的图片预处理节点配置 processors: - name: resize type: ResizeProcessor params: size: [224, 224] # 目标尺寸 interpolation: bicubic # 插值算法 - name: normalize type: NormalizeProcessor params: mean: [0.48145466, 0.4578275, 0.40821073] # CLIP特定的均值 std: [0.26862954, 0.26130258, 0.27577711] # CLIP特定的标准差 input_scale: 255 # 输入像素值范围是0-255注意事项处理器的顺序非常重要。通常的顺序是解码如ImageDecoder - 几何变换缩放、裁剪- 颜色空间转换如BGR转RGB- 归一化。错误的顺序可能导致模型性能下降甚至出错。务必参考目标模型官方文档的预处理流程。3.2 模型封装器统一的大模型交互接口Model节点是流水线的核心计算单元。OpenHarness 通过Model抽象屏蔽了不同模型框架PyTorch, TensorFlow, ONNX Runtime和推理后端本地、Triton、vLLM的差异。1. 本地模型封装对于部署在本地环境的模型框架提供了HuggingFaceModel、TorchScriptModel等封装器。以HuggingFaceModel为例你只需要指定模型在Hub上的ID或本地路径框架会自动处理模型加载、设备分配CPU/GPU和推理会话管理。# 在Python中定义模型节点示例 from openharness.models import HuggingFaceModel clip_model HuggingFaceModel( nameclip-vit-base-patch32, model_idopenai/clip-vit-base-patch32, modality[image, text], # 声明该模型支持多模态输入 taskzero-shot-image-classification, devicecuda:0, batch_size32 # 启用批处理以提升吞吐 )2. 远程推理服务集成在生产环境中模型可能部署在独立的推理服务器上如NVIDIA Triton。OpenHarness 提供了TritonModel等节点只需配置好服务的端点URL和模型名称就能像调用本地模型一样进行推理内部会处理gRPC/HTTP的通信、序列化和反序列化。3. 多模型与模型路由复杂的应用可能需要串联或并联多个模型。OpenHarness 的流水线可以轻松实现这种“模型链”。例如可以先用一个目标检测模型定位图中物体再裁剪出多个区域分别送入一个细粒度分类模型进行识别。框架会管理中间数据的传递和生命周期。踩坑记录模型节点的内存管理需要特别注意。尤其是视觉和语音模型输入数据如图像张量可能很大。如果流水线中有分支且多个下游节点都需要同一份原始数据默认情况下可能会产生多份拷贝导致内存激增。OpenHarness 的DataItem内部使用了类似“写时复制”的机制但在设计复杂流水线时仍需关注数据流必要时可以使用SharedDataProcessor来显式共享大块数据。3.3 流水线编排与调度引擎这是 OpenHarness 的“大脑”负责解析流水线定义调度节点执行管理数据流和错误处理。1. 执行引擎框架提供了两种主要的执行引擎同步引擎简单直接按节点定义顺序依次执行适合调试和简单线性流水线。异步引擎基于 asyncio可以并发执行没有依赖关系的节点充分利用I/O等待时间显著提升吞吐量是生产环境的默认选择。2. 错误处理与重试网络波动、模型暂时不可用、输入数据异常等问题在生产中无法避免。OpenHarness 的调度器为每个节点提供了可配置的错误处理策略retry_policy: 定义重试次数和退避策略如指数退避。fallback_node: 指定一个备用节点在主节点失败时接管。error_handler: 自定义错误处理逻辑如记录错误数据、发送告警、返回默认值等。3. 资源管理与限流为了避免单个流水线耗尽系统资源如GPU内存调度器支持资源配额和限流。你可以为流水线或单个模型节点设置最大并发数、GPU内存上限等。这对于多租户共享的推理服务平台至关重要。4. 从零构建一个多模态搜索应用完整实操理论说得再多不如动手做一遍。让我们用一个完整的例子构建一个支持“以图搜图”和“文本搜图”的简易多模态搜索服务。4.1 应用场景与架构设计假设我们有一个电商平台需要让用户上传一张商品图片就能找到平台上类似的商品或者用户输入一段文本描述如“红色的连衣裙”也能找到匹配的商品图。核心流程如下离线处理建库将商品库中的所有图片通过多模态模型如CLIP提取出特征向量存入向量数据库如Milvus、Qdrant。在线服务查询对于图片查询用户上传图片 - 提取特征向量 - 在向量库中搜索最近邻 - 返回相似商品ID。对于文本查询用户输入文本 - 提取文本特征向量 - 在向量库中搜索 - 返回结果。我们将用 OpenHarness 来构建在线查询服务部分。4.2 环境准备与依赖安装首先创建一个新的Python环境并安装核心依赖。# 创建并激活虚拟环境 python -m venv openharness-env source openharness-env/bin/activate # Linux/macOS # openharness-env\Scripts\activate # Windows # 安装OpenHarness核心库及额外组件 pip install openharness-core # 安装视觉相关的加载器和处理器 pip install openharness-vision # 安装HuggingFace模型支持 pip install openharness-model-hf # 安装用于HTTP服务的组件 pip install openharness-serving-http此外我们还需要安装向量数据库客户端。这里以 Qdrant 为例pip install qdrant-client4.3 构建特征提取流水线这是最核心的部分。我们需要创建一个流水线它能同时处理图片和文本输入并输出一个统一的特征向量。我们创建一个配置文件feature_extraction_pipeline.yaml# feature_extraction_pipeline.yaml version: 1.0 name: clip_feature_extractor nodes: # 节点1: 通用加载器根据输入类型分发 - id: input_dispatcher type: Dispatcher params: dispatch_by: input_type # 根据输入字段决定路由 routes: image: image_loader text: text_loader # 节点2: 图片加载与处理分支 - id: image_loader type: UrlLoader # 假设图片来自URL params: timeout_sec: 10 outputs: [image_raw] - id: image_decoder type: ImageDecoder inputs: [image_loader.image_raw] outputs: [image_tensor] - id: image_preprocess type: SequentialProcessor params: processors: - type: ResizeProcessor params: {size: [224, 224]} - type: NormalizeProcessor params: mean: [0.48145466, 0.4578275, 0.40821073] std: [0.26862954, 0.26130258, 0.27577711] input_scale: 255 inputs: [image_decoder.image_tensor] outputs: [image_processed] # 节点3: 文本加载与处理分支 - id: text_loader type: TextLoader # 直接加载文本 outputs: [text_raw] - id: text_tokenize type: TokenizerProcessor params: tokenizer_id: openai/clip-vit-base-patch32 max_length: 77 inputs: [text_loader.text_raw] outputs: [text_tokens] # 节点4: CLIP模型推理统一入口 - id: clip_model type: HuggingFaceModel params: model_id: openai/clip-vit-base-patch32 task: feature-extraction device: cuda # 或 cpu batch_size: 1 # 模型能接受来自两个分支的输入但一次只处理一种 inputs: image: image_preprocess.image_processed text: text_tokenize.text_tokens outputs: [feature_vector] # 节点5: 结果格式化 - id: output_formatter type: DictConstructor params: mapping: feature: clip_model.feature_vector input_type: input_dispatcher.input_type outputs: [final_output]这个流水线的巧妙之处在于使用了Dispatcher节点。它根据输入数据中input_type字段的值“image”或“text”将请求路由到不同的预处理分支最终汇聚到同一个clip_model节点进行特征提取。SequentialProcessor让我们可以把多个预处理步骤打包成一个节点使配置更清晰。4.4 创建查询服务并与向量数据库交互接下来我们编写主服务逻辑将流水线实例化并集成 Qdrant 向量数据库进行搜索。# app.py import asyncio from typing import Union, List from qdrant_client import QdrantClient from qdrant_client.models import Filter, SearchRequest import numpy as np from openharness import Pipeline from openharness.serving.http import HTTPServer, create_post_route # 1. 初始化向量数据库客户端 qdrant_client QdrantClient(hostlocalhost, port6333) COLLECTION_NAME product_images # 2. 加载特征提取流水线 pipeline Pipeline.from_yaml(feature_extraction_pipeline.yaml) # 3. 定义搜索函数 async def search_by_image(image_url: str, top_k: int 10) - List[dict]: 以图搜图 # 运行流水线提取特征 input_data {input_type: image, url: image_url} result await pipeline.run_async(input_data) query_vector result[final_output][feature_vector].squeeze().tolist() # 转换为列表 # 在Qdrant中搜索 search_result qdrant_client.search( collection_nameCOLLECTION_NAME, query_vectorquery_vector, limittop_k, with_payloadTrue # 返回存储的原始信息如商品ID、标题等 ) return [{id: hit.id, score: hit.score, payload: hit.payload} for hit in search_result] async def search_by_text(text: str, top_k: int 10) - List[dict]: 以文搜图 input_data {input_type: text, text: text} result await pipeline.run_async(input_data) query_vector result[final_output][feature_vector].squeeze().tolist() search_result qdrant_client.search( collection_nameCOLLECTION_NAME, query_vectorquery_vector, limittop_k, with_payloadTrue ) return [{id: hit.id, score: hit.score, payload: hit.payload} for hit in search_result] # 4. 创建HTTP路由并启动服务 app HTTPServer() # 注册搜索端点 app.route(/search/image, methods[POST]) async def image_search_endpoint(request): data await request.json() results await search_by_image(data[url], data.get(top_k, 10)) return {results: results} app.route(/search/text, methods[POST]) async def text_search_endpoint(request): data await request.json() results await search_by_text(data[text], data.get(top_k, 10)) return {results: results} if __name__ __main__: # 启动HTTP服务默认端口8080 app.run(host0.0.0.0, port8080)现在运行python app.py一个具备多模态搜索能力的HTTP服务就启动了。你可以用curl或Postman发送请求# 以图搜图 curl -X POST http://localhost:8080/search/image \ -H Content-Type: application/json \ -d {url: https://example.com/shoe.jpg, top_k: 5} # 以文搜图 curl -X POST http://localhost:8080/search/text \ -H Content-Type: application/json \ -d {text: 男士黑色运动鞋, top_k: 5}4.5 性能优化与生产部署建议上述示例是一个基础版本。要用于生产还需考虑以下几点流水线预热与缓存在服务启动后先用一些虚拟数据“预热”流水线特别是模型加载部分。对于相同的图片URL可以在UrlLoader前增加一个缓存节点避免重复下载。批处理优化当前配置batch_size: 1没有利用批处理优势。如果查询QPS高可以设计一个批处理队列将短时间内多个查询的特征提取请求批量送入模型能极大提升GPU利用率和吞吐量。OpenHarness 的异步引擎和模型节点对此有良好支持。服务高可用将上面的app.py打包成Docker镜像。在Kubernetes中部署多个副本并通过负载均衡器如Nginx Ingress对外暴露服务。为服务配置健康检查、就绪探针和资源限制。监控与告警利用 OpenHarness 内置的指标监控每个节点的处理延迟、成功率。为特征提取耗时、向量搜索耗时、Qdrant连接状态等关键指标设置告警。向量数据库优化根据数据量选择合适的索引类型如HNSW、IVF。对向量进行归一化使L2范数为1可以提升一些索引算法的效率和准确性。定期重建索引以应对数据增长。5. 常见问题排查与实战技巧实录在实际使用 OpenHarness 的过程中你肯定会遇到各种问题。下面是我和团队在多个项目中总结的一些典型问题和解决思路。5.1 流水线配置与执行问题问题1流水线启动时报错Node ‘xxx‘ not found或Invalid input port‘yyy‘。排查思路这是最常见的配置错误。首先使用框架提供的pipeline.validate()方法或命令行工具ohs validate pipeline.yaml对配置文件进行语法和语义检查。其次仔细核对节点ID的拼写。在inputs字段中引用其他节点的输出时格式必须是节点ID.输出端口名。确保所有被引用的节点ID和端口名都存在。技巧在编写复杂的、节点众多的流水线时建议先用纸笔画一下数据流图明确每个节点的输入输出再转化为YAML配置。可以分模块测试先让一小段流水线跑通再逐步添加。问题2处理图片或视频时内存占用过高甚至OOM内存溢出。排查思路多模态数据尤其是高分辨率图片和长视频非常吃内存。首先检查你的Processor链。如果在流水线早期节点如ImageDecoder就生成了高分辨率张量并且这个张量被复制到多个下游分支内存会成倍增长。解决方案尽早降采样在Loader或第一个Processor中就将图片缩放到模型需要的尺寸如224x224而不是先解码成全尺寸再缩放。使用流式处理器对于视频使用VideoFrameStreamLoader而不是一次性加载所有帧。配合BatchProcessor以“小批量”的方式处理帧序列。调整流水线设计如果业务允许考虑将“特征提取”和“后处理/分析”拆分成两个独立的流水线服务中间通过磁盘或内存数据库如Redis传递特征向量而不是原始数据。设置资源限制在运行流水线时通过PipelineConfig设置内存上限框架会在超限时抛出清晰异常而不是直接崩溃。问题3模型推理节点速度慢成为性能瓶颈。排查思路使用框架的监控指标或简单的计时定位耗时最长的节点。如果是模型节点解决方案启用批处理这是提升吞吐最有效的手段。确保模型节点的batch_size参数大于1并且上游数据能组织成批次。对于在线服务可能需要一个异步的批处理队列来累积请求。检查硬件利用使用nvidia-smi或htop查看GPU/CPU利用率。如果利用率低可能是数据预处理CPU部分太慢拖累了GPU。考虑使用异步引擎让CPU预处理和GPU推理重叠执行。考虑模型优化将模型转换为 TensorRT 或 ONNX Runtime 格式通常能获得显著的加速。OpenHarness 的ONNXModel或TensorRTModel节点可以无缝接入。升级推理后端对于LLM或大型视觉模型考虑使用专门的推理服务器如 vLLM 或 Triton并通过 OpenHarness 的对应节点进行调用它们通常有更高效的内存管理和调度策略。5.2 模型与数据处理问题问题4同一套预处理流程为什么我的模型效果比直接用原版代码差排查思路99%的问题出在数据预处理上。多模态模型对输入数据的归一化、裁剪、尺寸等极其敏感。排查步骤数值比对写一个简单的测试脚本用原版预处理代码和你的 OpenHarness 流水线处理同一张图片分别得到两个张量。计算它们的绝对差值如torch.abs(tensor1 - tensor2).max()如果差值大于一个很小的阈值如1e-5说明预处理不一致。逐层检查将你的预处理Processor链逐个禁用对比中间结果。常见差异点包括RGB/BGR通道顺序、归一化使用的均值和标准差、插值算法bilinearvsbicubic、裁剪时是否对齐角落等。参考官方实现直接去模型官方的 GitHub 仓库找到其预处理代码通常是transform.py或preprocess.py严格按照它的步骤和参数来配置你的Processor。问题5处理一批数据时偶尔会出现个别数据失败导致整个批次被丢弃。解决方案不要因为一条坏数据而影响整个服务。OpenHarness 的节点级错误处理策略可以帮到你。- id: my_model type: HuggingFaceModel params: {...} error_policy: on_error: skip_item # 跳过当前出错的数据项继续处理批次中的其他项 max_errors_per_batch: 2 # 一个批次中最多容忍2个错误超过则整个批次失败 fallback_output: null_vector # 可以为出错项返回一个预定义的默认值如零向量同时在Loader阶段也要加强健壮性例如使用UrlLoader时设置重试和超时使用ImageDecoder时捕获损坏文件异常并返回错误标记。5.3 部署与运维问题问题6如何将OpenHarness流水线打包成Docker镜像技巧创建一个高效的Dockerfile。核心是利用分层构建减少镜像大小并确保推理环境一致。# 使用轻量级基础镜像 FROM python:3.10-slim # 安装系统依赖如对于图像处理可能需要libgl1 RUN apt-get update apt-get install -y --no-install-recommends \ libgl1-mesa-glx \ libglib2.0-0 \ rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /app # 先复制依赖文件利用Docker缓存层 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 再复制应用代码 COPY . . # 设置启动命令 CMD [python, app.py]requirements.txt中应精确固定所有包的版本特别是openharness-*系列包和torch以避免环境差异。问题7服务运行一段时间后响应延迟逐渐变长。排查思路这是典型的内存泄漏或资源未释放症状。排查步骤监控内存使用psutil或容器监控工具观察服务进程的内存增长趋势。如果持续增长而不回落很可能存在泄漏。检查自定义代码如果你在流水线中注入了自定义的Processor或Model节点重点检查其中是否有全局变量、静态容器在不断累积数据或者是否有文件句柄、网络连接未正确关闭。检查框架节点某些Loader如连接到数据库的可能维护了连接池。确认配置了合理的连接超时和最大空闲时间。使用分析工具对于Python应用可以使用objgraph或tracemalloc来追踪内存中对象增长的类型和引用链定位泄漏源。定期重启作为临时应对措施可以在Kubernetes中为部署配置livenessProbe和restartPolicy让不健康的Pod自动重启。但这只是治标仍需找到根本原因。经过多个项目的实践我的体会是OpenHarness 最大的价值在于它提供了一套“思维框架”和“工程标准”。它强迫你将一个杂乱的多模态应用拆解成标准化的组件并用清晰的数据流连接起来。这个过程本身就是对系统架构的一次深度梳理。初期可能会觉得配置有些繁琐但一旦习惯这种模式开发效率和系统的可维护性、可观测性都会得到质的提升。它可能不是解决所有问题的最快刀但绝对是构建稳健、可扩展的多模态AI应用时非常值得放入工具箱的利器。

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