基于视觉语言模型的图像文档检索:LitePali轻量级实现与应用

news2026/5/5 0:33:41
1. 项目概述与核心价值最近在折腾文档检索系统特别是那种需要从一堆扫描件、截图或者PDF转换来的图片里找内容的场景传统基于纯文本的搜索经常抓瞎。比如你有一堆学术论文的扫描版想找“关于神经网络注意力机制在2023年的优化方法”的相关段落光靠OCR提取文字再搜索不仅会漏掉图表里的关键信息对排版、公式的理解也几乎为零。这正是多模态检索——结合视觉和语言理解——能大显身手的地方。我尝试了市面上一些方案要么部署复杂、依赖沉重要么在云环境里跑起来资源开销太大。于是我动手搞了LitePali一个轻量级的、专为图像文档检索设计的工具库。它的核心是复用并优化了ColPali这个视觉语言模型的架构目标就一个让你能用最简单的依赖和最少的配置快速构建一个能“看懂”图片文档内容的语义搜索引擎。简单说LitePali 是一个 Python 库。你给它一堆文档图片JPG、PNG 都行它利用背后的视觉语言模型为每一张图片生成一个富含语义的“向量指纹”。当你想搜索时把你的问题比如“找出所有讨论碳排放交易的图表”也变成一个向量然后系统会快速比对找出和你问题向量最相似的图片。这比单纯匹配关键词高级多了因为它真正在尝试理解图片里图文混排的内容。我设计时特别考虑了云部署和批量处理的效率去掉了对 Poppler 这类 PDF 解析库的强依赖把数据处理流程做得尽可能确定和高效。如果你正在构建涉及文档理解、知识库问答或者检索增强生成的应用并且数据源包含大量图像格式的文档那么 LitePali 提供的这条技术路径值得你花时间深入了解。2. 核心架构与模型原理深度解析2.1 为什么是视觉语言模型在深入 LitePali 之前得先搞清楚它凭什么能“看懂”图片。传统文档处理流水线通常是“PDF - PDF解析器 - 页面渲染 - OCR - 纯文本 - 文本向量化”。这个链条长每个环节都可能出错PDF解析库版本兼容性问题、OCR对复杂排版识别率低、丢失所有视觉信息。视觉语言模型直接颠覆了这个流程。以 ColPali 为代表的模型其训练数据就是海量的图像文本对。模型通过一个视觉编码器通常是 Vision Transformer提取图像的网格特征同时用一个文本编码器处理对应的描述文本在训练过程中让模型学会将图像特征和文本特征在共享的语义空间中对齐。这意味着一个训练好的 VLM看到一张包含文字和图的文档页时它提取的特征已经是一个融合了视觉元素图表、排版、字体大小和语义内容文字含义的混合体。LitePali 直接站在 ColPali 的肩膀上省去了自己从头训练模型的巨大成本专注于如何高效地使用这个模型进行检索。2.2 ColPali 的“晚期交互”机制精要ColPali 模型架构中一个关键设计是Late Interaction这也是 LitePali 检索效率的基石。为了理解它我们先看看常见的两种向量检索方式单向量表示将整张图片或整段文本编码成一个固定长度的向量比如768维。检索时计算查询向量和所有文档向量的余弦相似度。优点是索引小、速度快但缺点是把丰富的细节压缩到一个向量里可能丢失细粒度信息。早期交互像BERT的交叉编码器将查询和文档一起输入模型直接计算相关性分数。精度通常最高但计算成本巨大无法预先索引每次查询都需要遍历所有文档完全不适合大规模检索。ColPali 采用的Late Interaction是一种巧妙的折中它属于“多向量表示”家族。具体到 ColPali编码阶段模型不是为整张图片生成一个向量而是生成一组向量。可以理解为模型把图片划分成许多个“语义块”可能对应段落、图表、标题等为每个块生成一个特征向量。同时查询文本也会被分词后每个词或子词也生成对应的向量。交互阶段在检索时计算查询的每个向量与文档的每个向量之间的相似度矩阵然后通过一个聚合函数比如取最大值、平均值得到一个最终的相关性分数。因为向量间的交互计算发生在编码之后且可以通过高效的矩阵运算完成所以它比交叉编码器快得多同时又比单向量表示保留了更丰富的匹配信号。在 LitePali 的实现中colpali-engine这个底层库封装了所有这些复杂的计算。当我们调用litepali.process()时背后就是在用 ColPali 模型为每一张添加的图片计算这组多向量表示。而litepali.search()时则是用同样的模型处理查询文本并执行高效的晚期交互匹配计算。2.3 LitePali 的工程化取舍理解了模型再看 LitePali 的设计选择就清晰了。它明确只处理图像。这是一个非常重要的工程取舍。优势依赖极简彻底摆脱了对pdf2image、PyMuPDF或poppler的依赖。在Docker化或Serverless部署时镜像体积更小构建更简单尤其适合CPU-only环境做预处理GPU环境做推理的分离架构。流程解耦将“文档格式转换”和“语义理解检索”两个关注点分离。你可以用任何你喜欢的、最稳定的工具比如部署在另一个服务里的pdftoppm把PDF转为图片然后将图片路径交给 LitePali。这样PDF解析的崩溃不会影响你的检索服务。确定性对于同一张图片多次处理得到的向量表示是确定的。这保证了搜索结果的可复现性对于调试和线上服务至关重要。需要使用者处理的你需要在调用 LitePali 之前自己完成 PDF 到图像的转换。这看似多了一步但实际上给了你更大的灵活性。比如你可以控制转换的分辨率DPI平衡清晰度和处理速度你也可以只转换感兴趣的页码节省资源。3. 从零开始安装与环境配置实战3.1 基础安装与验证安装 LitePali 非常简单一行 pip 命令即可。但根据我的经验一个干净的环境是成功的第一步。# 强烈建议在虚拟环境中操作 python -m venv litepali-env source litepali-env/bin/activate # Linux/macOS # 或 litepali-env\Scripts\activate # Windows # 安装 LitePali它会自动安装 colpali-engine 等核心依赖 pip install litepali安装完成后不要急着写代码先做一个快速验证确认关键依赖特别是 PyTorch 的版本是兼容的。# verification.py import torch import litepali from colpali_engine import ColPaliProcessor # 尝试导入底层引擎 print(fPyTorch version: {torch.__version__}) print(fLitePali version: {litepali.__version__}) print(fCUDA available: {torch.cuda.is_available()}) # 检查GPU是否可用运行这个脚本如果没报错并且输出显示了版本号说明基础安装成功。这里有个关键点colpali-engine对 PyTorch 版本可能有特定要求。虽然 LitePali 声明兼容 PyTorch 1.8但在实际生产环境中我推荐使用 PyTorch 1.12 或 2.0 以上的稳定版本以获得更好的性能和兼容性。如果你遇到版本冲突可以尝试先安装指定版本的 PyTorch再安装 LitePali。3.2 模型下载与缓存策略第一次初始化LitePali()或进行任何处理时系统会自动从 Hugging Face Hub 下载预训练的 ColPali 模型权重。这个过程可能会比较慢取决于你的网络。模型保存位置默认情况下模型会下载到~/.cache/huggingface/hub目录。你可以通过设置环境变量TRANSFORMERS_CACHE来改变这个路径这在容器化部署时很有用可以把缓存挂载到持久化存储上。export TRANSFORMERS_CACHE/path/to/your/cache离线部署在内网或无外网环境部署时你需要提前在有网机器下载好模型。在有网环境运行一次你的脚本触发下载。将整个~/.cache/huggingface/hub目录打包。在离线环境解压到相同路径或通过TRANSFORMERS_CACHE指向你解压的目录。注意模型文件通常有几个GB大小请确保部署目标机器有足够的磁盘空间。同时加载模型需要较大的内存RAM在内存有限的云函数环境中需要特别注意。3.3 硬件考量与性能预估GPU vs CPUColPali 模型推理在 GPU 上会有百倍的速度提升。对于生产环境强烈推荐使用 GPU。LitePali 会自动利用可用的 CUDA 设备。如果没有 GPU它会在 CPU 上运行但处理速度会非常慢只适合小规模测试。内存消耗处理一张标准 A4 纸约 2000x2800 像素的图片模型加载后单张图片的向量化过程在 GPU 上可能需要 1-2GB 的显存。批量处理 (batch processing) 能显著提高吞吐量但也会线性增加显存占用。你需要根据你的 GPU 显存大小来调整批量大小这在 LitePali 的process方法中通常有参数可以控制。测试建议在投入生产前用你的典型文档图片10-100张做一个端到端的性能测试。记录add,process,search三个阶段的耗时和内存/显存占用。这能帮你准确预估资源需求。4. 核心API详解与最佳实践4.1 初始化与资源管理LitePali类的初始化看似简单但有几个隐含的要点。from litepali import LitePali # 最简单的初始化 lp LitePali() # 更推荐的初始化方式显式指定模型和设备 import torch device cuda if torch.cuda.is_available() else cpu lp LitePali(model_namecolpali-base, devicedevice) # 可以指定模型变体model_name: 虽然当前可能只支持colpali-base但留出这个参数为未来支持更多模型如colpali-large提供了可能。指定它可以使代码意图更清晰。device: 显式指定设备是一个好习惯。尤其是在混合环境中比如有多个GPU你可以通过devicecuda:0来指定使用哪一块GPU。重要实践LitePali对象会加载一个大模型它是一个重资源对象。在你的应用中比如 Web 服务你应该将它设计为单例在服务启动时初始化一次然后在所有请求中复用。反复创建和销毁LitePali实例会导致模型重复加载消耗大量时间和内存。4.2 构建索引add与process的学问索引构建是检索系统的数据准备阶段这里的操作决定了后续检索的质量和效率。from litepali import ImageFile import os # 假设我们有一个文档库结构如下 # documents/ # doc_001.pdf - 已转换为 images/doc_001_page_01.jpg, ... # doc_002.pdf - ... litepali LitePali() image_files [] # 遍历文档图像 doc_base ./documents/images for doc_dir in os.listdir(doc_base): doc_path os.path.join(doc_base, doc_dir) if os.path.isdir(doc_path): doc_id int(doc_dir.split(_)[1]) # 从文件夹名提取文档ID for page_file in sorted(os.listdir(doc_path)): # 按文件名排序保证页码顺序 if page_file.endswith((.jpg, .png, .jpeg)): page_num int(page_file.split(_)[-1].split(.)[0]) # 提取页码 full_path os.path.join(doc_path, page_file) # 构造丰富的元数据 metadata { doc_id: doc_id, title: fDocument {doc_id}, source_file: fdoc_{doc_id:03d}.pdf, page_number: page_num, added_time: 2023-10-27 } # 创建ImageFile对象 img_file ImageFile( pathfull_path, document_iddoc_id, # 同一文档的不同页document_id相同 page_idpage_num, # 页码作为page_id metadatametadata ) image_files.append(img_file) # 批量添加LitePali内部可能优化了批量添加的逻辑 for img in image_files: litepali.add(img) # 关键一步处理所有添加的图片生成向量索引 print(开始处理图片生成向量索引...) litepali.process() # 这里会调用模型进行前向传播耗时较长 print(处理完成)ImageFile是关键数据结构它把图片路径、逻辑标识文档ID、页码和业务元数据绑定在一起。document_id和page_id对于组织结果非常重要好的设计能让搜索结果更易用例如返回时按文档分组。元数据metadata的妙用你可以把任何结构化信息塞进去比如作者、分类、发布日期。未来进行高级过滤时虽然当前API未直接支持但你可以搜索后对结果进行过滤这些数据就派上用场了。process()是瓶颈这个方法会触发实际的模型推理为所有图片生成向量表示。这是整个流程中最耗时的步骤需要GPU加速。对于大规模文档集上万张图片你需要设计异步或离线任务来处理并考虑进度保存和断点续处理。4.3 执行搜索理解结果与调优搜索是系统的核心输出。# 执行搜索 query 机器学习模型训练过程中的过拟合问题如何解决 top_k 10 # 返回最相关的10个结果 results litepali.search(query, ktop_k) # 解析和展示结果 print(f查询: {query}) print(f找到 {len(results)} 个相关结果:\n) for i, result in enumerate(results): img_file_obj result[image] # 这是一个ImageFile对象 score result[score] # 相关性分数越高越相关 print(f结果 #{i1} (得分: {score:.4f})) print(f 文档ID: {img_file_obj.document_id}) print(f 页码: {img_file_obj.page_id}) print(f 图片路径: {img_file_obj.path}) print(f 元数据: {img_file_obj.metadata.get(title, N/A)}) print(- * 40)理解score这个分数是查询和文档向量经过 Late Interaction 计算后的相似度分数。它不是一个概率值也没有绝对阈值。通常你只需要关心结果的相对排序。分数越高表示模型认为该图片与你的查询语义上越相关。k参数的选择设置k取决于你的应用场景。如果是召回最相关的一页给用户看k5或k10可能就够了。如果是作为 RAG 的检索器为一个大语言模型提供上下文你可能需要k20或更多以获取更全面的信息。搜索性能一旦索引构建完成搜索速度是非常快的因为主要计算是高效的向量相似度计算。即使有数十万条向量在GPU上也能在毫秒到秒级返回结果。4.4 索引的持久化save与load索引构建耗时耗力必须能保存和加载。index_path ./my_document_index.lp # 保存索引保存的是向量数据和元数据不是图片本身 litepali.save_index(index_path) print(f索引已保存至 {index_path}) # 在另一个进程或服务中加载索引 new_lp LitePali() new_lp.load_index(index_path) print(索引加载成功可以立即进行搜索。) # 现在 new_lp 可以像之前一样使用 search 方法保存了什么save_index保存的是每张图片对应的向量表示即模型提取的特征以及你通过ImageFile传入的所有信息path,document_id,page_id,metadata。它不保存图片的原始像素数据。这意味着加载索引后系统仍然需要能通过path访问到原始图片文件如果你后续需要展示图片的话。文件格式与兼容性索引文件格式是库内部定义的。不同版本的 LitePali 或colpali-engine生成的索引文件可能不兼容。在升级版本时建议重新构建索引。TODO中的增强项目计划中提到未来会将图片的 base64 编码也存入索引。这将实现真正的“自包含”加载索引后无需再访问原始文件对于部署到无法直接访问文件系统的环境如某些 serverless 平台非常有用。5. 实战构建一个简单的文档问答服务让我们把 LitePali 用起来构建一个简单的命令行文档问答工具。这个例子将串联从 PDF 到答案的完整流程。5.1 步骤一文档预处理流水线首先我们需要一个独立的脚本将 PDF 文档库转换为图像并用 LitePali 建立索引。这个脚本通常只需运行一次。# build_index.py import os from pathlib import Path from litepali import LitePali, ImageFile import fitz # PyMuPDF用于PDF转图像。这是一个可选依赖你需要单独安装。 def pdf_to_images(pdf_path, output_dir, dpi150): 使用 PyMuPDF 将 PDF 每一页转换为 JPEG 图像 doc fitz.open(pdf_path) image_paths [] for page_num in range(len(doc)): page doc.load_page(page_num) pix page.get_pixmap(dpidpi) img_path output_dir / fpage_{page_num1:03d}.jpg pix.save(str(img_path)) # 保存为JPEG image_paths.append(str(img_path)) doc.close() return image_paths def build_index(pdf_folder, image_output_base, index_save_path): 遍历PDF文件夹转换并构建索引 lp LitePali(devicecuda) # 假设有GPU pdf_folder Path(pdf_folder) image_output_base Path(image_output_base) image_output_base.mkdir(parentsTrue, exist_okTrue) all_image_files [] doc_id_counter 0 for pdf_file in pdf_folder.glob(*.pdf): doc_id_counter 1 doc_name pdf_file.stem # 为每个PDF创建独立的图片输出子目录 doc_image_dir image_output_base / doc_name doc_image_dir.mkdir(exist_okTrue) print(f正在处理: {pdf_file.name}) image_paths pdf_to_images(pdf_file, doc_image_dir) for idx, img_path in enumerate(image_paths): metadata { document_name: doc_name, source_pdf: str(pdf_file.name), total_pages: len(image_paths) } img_obj ImageFile( pathimg_path, document_iddoc_id_counter, page_ididx1, metadatametadata ) all_image_files.append(img_obj) # 批量添加并处理 print(f开始添加 {len(all_image_files)} 张图片到索引...) for img_obj in all_image_files: lp.add(img_obj) print(开始处理图片向量化这可能需要一些时间...) lp.process() print(f保存索引到 {index_save_path}...) lp.save_index(index_save_path) print(索引构建完成) return lp if __name__ __main__: # 配置你的路径 PDF_FOLDER ./my_pdfs IMAGE_OUTPUT ./pdf_images INDEX_PATH ./document_index.idx # 运行索引构建 build_index(PDF_FOLDER, IMAGE_OUTPUT, INDEX_PATH)5.2 步骤二问答服务脚本索引建好后我们写一个简单的交互式问答脚本。# query_service.py from litepali import LitePali import sys class DocumentQAService: def __init__(self, index_path): print(正在加载文档索引...) self.lp LitePali() self.lp.load_index(index_path) print(f索引加载完成共加载了 {len(self.lp._get_internal_image_list())} 个文档页面。) # 注意这里用了假设的内部方法实际可能需要通过其他方式获取数量 def search_and_respond(self, query, top_k5): 检索最相关的文档页 print(f\n 正在搜索: {query}) results self.lp.search(query, ktop_k) if not results: print(未找到相关文档。) return [] print(f\n找到 {len(results)} 个相关页面:) for i, res in enumerate(results): img_obj res[image] print(f\n[{i1}] 相关性: {res[score]:.3f}) print(f 文档: {img_obj.metadata.get(document_name, Unknown)}) print(f 页码: {img_obj.page_id}) print(f 来源: {img_obj.metadata.get(source_pdf, N/A)}) # 在实际应用中这里可以拼接检索到的文本需OCR或图片路径发送给LLM生成答案 return results if __name__ __main__: INDEX_PATH ./document_index.idx # 与构建索引时使用的路径一致 service DocumentQAService(INDEX_PATH) print(\n 文档问答系统 ) print(输入你的问题输入 quit 或 exit 退出) while True: try: user_query input(\n问: ).strip() if user_query.lower() in [quit, exit, q]: print(再见) break if not user_query: continue service.search_and_respond(user_query) except KeyboardInterrupt: print(\n程序被中断。) break except Exception as e: print(f发生错误: {e})5.3 步骤三与LLM结合实现RAG单纯的检索只找到了相关文档片段。要生成自然语言答案我们需要引入一个大语言模型。这里展示一个概念性流程。# 假设我们已经有了检索结果 top_results top_results service.search_and_respond(user_query, top_k3) # 1. 从检索到的图片中提取文本这里需要OCR例如使用pytesseract或EasyOCR # 这是一个简化的示例实际应用需要集成OCR库 def extract_text_from_image(image_path): import pytesseract from PIL import Image # 实现OCR逻辑 image Image.open(image_path) text pytesseract.image_to_string(image, langengchi_sim) # 中英文 return text # 2. 构建LLM的上下文 context_parts [] for res in top_results: img_path res[image].path page_text extract_text_from_image(img_path) # 可以添加一些引用信息 context_parts.append(f[来自文档 {res[image].metadata.get(document_name)} 第{res[image].page_id}页]:\n{page_text}\n) context \n---\n.join(context_parts) # 3. 构造Prompt调用LLM API (例如 OpenAI, 或本地部署的 Llama) prompt f基于以下提供的文档片段请回答用户的问题。如果文档中没有足够信息请如实说明。 文档片段 {context} 用户问题{user_query} 请给出详细、准确的回答 # 4. 调用LLM (伪代码) # answer call_llm_api(prompt, modelgpt-4) # print(f答: {answer})这个流程就是检索增强生成的典型模式LitePali 充当了检索器的角色从海量非结构化文档中精准找到相关片段LLM 作为生成器基于这些高质量的上下文生成准确、可靠的答案。两者结合有效解决了LLM的幻觉问题和知识截止问题。6. 部署考量、常见问题与优化方向6.1 生产环境部署策略将 LitePali 用于生产你需要考虑以下几个层面服务化不要在每个请求中初始化LitePali。应该将其封装为一个长期运行的服务如使用 FastAPI 或 Flask 构建 Web API。服务启动时加载模型和索引后续请求共享这个实例。# fastapi_app.py 示例片段 from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel import uvicorn app FastAPI() # 全局变量在启动时加载 lp_service None app.on_event(startup) async def startup_event(): global lp_service lp_service DocumentQAService(./prod_index.idx) class QueryRequest(BaseModel): question: str top_k: int 5 app.post(/search) async def search_docs(request: QueryRequest): results lp_service.search_and_respond(request.question, request.top_k) # 将结果格式化为JSON返回 return {results: results}资源隔离模型推理是计算密集型任务。考虑使用消息队列如 Redis, RabbitMQ将索引构建process这类重型任务放到后台工作进程处理避免阻塞主API线程。索引更新如何应对新增文档全量重建索引成本高。一个可行的策略是定期如每天凌晨运行一个离线任务处理新增文档生成增量索引片段然后与主索引合并。LitePali 目前可能需要你自行管理这个合并逻辑例如维护一个记录所有已索引ImageFile的列表新增时重新add并process然后save_index覆盖。6.2 常见问题与排查问题process()时 GPU 内存溢出OOM原因一次性处理的图片批量太大。虽然 LitePali 内部可能做了批处理但总图片数过多或单张图片分辨率过高都会导致显存不足。解决降低输入图片的分辨率。在 PDF 转图像时使用较低的 DPI如 150 甚至 100。分批处理。不要一次性add所有图片然后process。可以每添加 N 张如 50 张就调用一次process()然后考虑如何合并这些分批生成的索引这需要自定义逻辑因为标准API可能不支持索引合并。启用梯度检查点或使用更小的模型变体如果未来支持。问题搜索速度随着索引增大而变慢原因暴力计算查询向量与所有文档向量的相似度复杂度是 O(N)。当 N文档数达到数十万时延迟会变得明显。解决这是向量检索的经典问题。LitePali/ColPali 本身可能没有集成近似最近邻搜索库。一个高级的优化方案是将 LitePali 生成的向量导出导入到专业的向量数据库如FAISS,Milvus,Qdrant,Weaviate中。这些数据库提供了高效的 ANN 算法能在精度损失很小的情况下将检索速度提升几个数量级。你需要编写适配代码将ImageFile的元数据与向量一起存储到这些数据库中。问题搜索结果不相关原因图片质量差模糊、倾斜、光照不均的图片严重影响 VLM 的特征提取。查询表述不当VLM 理解的是语义过于简短或口语化的查询可能匹配不佳。领域不匹配ColPali 是在通用文档数据上训练的如果你的文档是极端专业领域如古文字、特殊符号效果可能打折。解决预处理时确保图片清晰、方正。尝试用更完整、更书面的语言重构用户查询即“查询重写”这本身可以是一个 LLM 的前置任务。考虑对 ColPali 模型在你的专业数据上进行轻量级的微调但这需要一定的机器学习专业知识。6.3 性能优化与未来展望结合项目的 TODO 列表我们可以预见一些优化方向Flash Attention 集成如果colpali-engine未来集成 Flash Attention将在处理高分辨率图片或更长序列时大幅减少显存占用并提升速度。关注项目更新及时升级。模型量化int8或int4量化能将模型大小减少数倍推理速度提升并允许在更小的 GPU 甚至 CPU 上部署。这是部署到边缘设备的关键。混合检索LitePali 提供了强大的多模态语义检索。但在实际系统中可以将其与传统的关键词检索如 BM25结合。例如先使用关键词快速筛选出一批候选文档再用 LitePali 进行精排。这种“召回-精排”两阶段策略能兼顾速度和精度。索引压缩与优化探索更高效的向量压缩技术如乘积量化在几乎不损失精度的情况下将索引大小减少一个数量级使其能完全放入内存实现亚毫秒级检索。LitePali 作为一个年轻的项目它精准地切入了一个痛点轻量、专注的图像文档检索。它可能不是功能最全的但它的设计哲学——简单、直接、云原生——让它成为快速原型开发和特定场景部署的绝佳选择。随着多模态 AI 的快速发展这类工具的价值只会越来越大。

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