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

通过阿里云Milvus与通义千问VL大模型,快速实现多模态搜索

本文主要演示了如何使用阿里云向量检索服务Milvus版与通义千问VL大模型,提取图片特征,并使用多模态Embedding模型,快速实现多模态搜索。

基于灵积(Dashscope)模型服务上的通义千问 API以及Embedding API来接入图片、文本等非结构化数据Embedding为向量的能力。

通义千问VL大模型介绍《通义千问VL API详情》

通义多模态向量模型介绍《Multimodal-Embedding API详情》

前提条件

  • 已创建阿里云Milvus实例。具体操作,请参见快速创建Milvus实例。

  • 已开通服务并获得API-KEY。具体操作,请参见开通DashScope并创建API-KEY。

该示例的运行环境为python3.9

python3 -m pip install dashscope pymilvus==2.5.0

wget https://github.com/milvus-io/pymilvus-assets/releases/download/imagedata/reverse_image_search.zip
unzip -q -o reverse_image_search.zip

示例代码

在本文示例中,我们先将示例图片通过通义千问VL提取图片描述,存储在image_description中,然后将图片描述和图片通过多模态Embedding模型分别转换为向量存储在image_embedding和text_embedding中。

备注:在该示例中,仅以数据集前200张图片作为演示

import base64
import csv
import dashscope
import os
import pandas as pd
import sys
import time
from tqdm import tqdm
from pymilvus import (connections,FieldSchema,CollectionSchema,DataType,Collection,MilvusException,utility,
)from http import HTTPStatus
import logginglogging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)class FeatureExtractor:def __init__(self, DASHSCOPE_API_KEY):self._api_key = DASHSCOPE_API_KEY  # 使用环境变量存储API密钥def __call__(self, input_data, input_type):if input_type not in ("image", "text"):raise ValueError("Invalid input type. Must be 'image' or 'text'.")try:if input_type == "image":_, ext = os.path.splitext(input_data)image_format = ext.lstrip(".").lower()with open(input_data, "rb") as image_file:base64_image = base64.b64encode(image_file.read()).decode("utf-8")input_data = f"data:image/{image_format};base64,{base64_image}"payload = [{"image": input_data}]else:payload = [{"text": input_data}]resp = dashscope.MultiModalEmbedding.call(model="multimodal-embedding-v1",input=payload,api_key=self._api_key,)if resp.status_code == HTTPStatus.OK:return resp.output["embeddings"][0]["embedding"]else:raise RuntimeError(f"API调用失败,状态码: {resp.status_code}, 错误信息: {resp.message}")except Exception as e:logger.error(f"处理失败: {str(e)}")raiseclass FeatureExtractorVL:def __init__(self, DASHSCOPE_API_KEY):self._api_key = DASHSCOPE_API_KEY  # 使用环境变量存储API密钥def __call__(self, input_data, input_type):if input_type not in ("image"):raise ValueError("Invalid input type. Must be 'image'.")try:if input_type == "image":payload=[{"role": "system","content": [{"type":"text","text": "You are a helpful assistant."}]},{"role": "user","content": [# {"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},{"image": input_data},{"text": "先用50字内的文字描述这张图片,然后再给出5个关键词"}],}]resp = dashscope.MultiModalConversation.call(model="qwen-vl-plus",messages=payload,api_key=self._api_key,)if resp.status_code == HTTPStatus.OK:return resp.output["choices"][0]["message"].content[0]["text"]else:raise RuntimeError(f"API调用失败,状态码: {resp.status_code}, 错误信息: {resp.message}")except Exception as e:logger.error(f"处理失败: {str(e)}")raiseclass MilvusClient:def __init__(self, MILVUS_TOKEN, MILVUS_HOST, MILVUS_PORT, INDEX, COLLECTION_NAME):self._token = MILVUS_TOKENself._host = MILVUS_HOSTself._port = MILVUS_PORTself._index = INDEXself._collection_name = COLLECTION_NAMEself._connect()self._create_collection_if_not_exists()def _connect(self):try:connections.connect(alias="default", host=self._host, port=self._port, token=self._token)logger.info("Connected to Milvus successfully.")except Exception as e:logger.error(f"连接Milvus失败: {str(e)}")sys.exit(1)def _collection_exists(self):return self._collection_name in utility.list_collections()def _create_collection_if_not_exists(self):try:if not self._collection_exists():fields = [FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),FieldSchema(name="origin", dtype=DataType.VARCHAR, max_length=512),FieldSchema(name="image_description", dtype=DataType.VARCHAR, max_length=1024),FieldSchema(name="image_embedding", dtype=DataType.FLOAT_VECTOR, dim=1024),FieldSchema(name="text_embedding", dtype=DataType.FLOAT_VECTOR, dim=1024)]schema = CollectionSchema(fields)self._collection = Collection(self._collection_name, schema)if self._index == 'IVF_FLAT':self._create_ivf_index()else:self._create_hnsw_index()   logger.info("Collection created successfully.")else:self._collection = Collection(self._collection_name)logger.info("Collection already exists.")except Exception as e:logger.error(f"创建或加载集合失败: {str(e)}")sys.exit(1)def _create_ivf_index(self):index_params = {"index_type": "IVF_FLAT","params": {"nlist": 1024, # Number of clusters for the index},"metric_type": "L2",}self._collection.create_index("image_embedding", index_params)self._collection.create_index("text_embedding", index_params)logger.info("Index created successfully.")def _create_hnsw_index(self):index_params = {"index_type": "HNSW","params": {"M": 64, # Maximum number of neighbors each node can connect to in the graph"efConstruction": 100, # Number of candidate neighbors considered for connection during index construction},"metric_type": "L2",}self._collection.create_index("image_embedding", index_params)self._collection.create_index("text_embedding", index_params)logger.info("Index created successfully.")def insert(self, data):try:self._collection.insert(data)self._collection.load()logger.info("数据插入并加载成功.")except MilvusException as e:logger.error(f"插入数据失败: {str(e)}")raisedef search(self, query_embedding, feild, limit=3):try:if self._index == 'IVF_FLAT':param={"metric_type": "L2", "params": {"nprobe": 10}}else:param={"metric_type": "L2", "params": {"ef": 10}}result = self._collection.search(data=[query_embedding],anns_field=feild,param=param,limit=limit,output_fields=["origin", "image_description"],)return [{"id": hit.id, "distance": hit.distance, "origin": hit.origin, "image_description": hit.image_description} for hit in result[0]]except Exception as e:logger.error(f"搜索失败: {str(e)}")return Nonedef load_image_embeddings(extractor, extractorVL, csv_path):df = pd.read_csv(csv_path)image_embeddings = {}for image_path in tqdm(df["path"].tolist()[:200], desc="生成图像embedding"): # 仅用前100张图进行演示try:desc = extractorVL(image_path, "image")image_embeddings[image_path] = [desc, extractor(image_path, "image"), extractor(desc, "text")]time.sleep(1)  # 控制API调用频率except Exception as e:logger.warning(f"处理{image_path}失败,已跳过: {str(e)}")return [{"origin": k, 'image_description':v[0], "image_embedding": v[1], 'text_embedding': v[2]} for k, v in image_embeddings.items()]

数据准备

if __name__ == "__main__":MILVUS_HOST = "c-xxxxxxxxxxxx.milvus.aliyuncs.com"MILVUS_PORT = "19530"MILVUS_TOKEN = "root:password"COLLECTION_NAME = "multimodal_search"INDEX = "IVF_FLAT" # IVF_FLAT OR HNSW# Step1:初始化Milvus客户端milvus_client = MilvusClient(MILVUS_TOKEN, MILVUS_HOST, MILVUS_PORT, INDEX, COLLECTION_NAME)DASHSCOPE_API_KEY = ""# Step2:初始化千问VL大模型与多模态Embedding模型extractor = FeatureExtractor(DASHSCOPE_API_KEY)extractorVL = FeatureExtractorVL(DASHSCOPE_API_KEY)# Step3:将图片数据集Embedding后插入到Milvusembeddings = load_image_embeddings(extractor, extractorVL, "reverse_image_search.csv")milvus_client.insert(embeddings)

在Step1中将Collection创建完成后,可以在控制台登录Attu,查看Collection Schema信息,如下图所示。

在完成Step3后,可以在Attu中查看插入数据,此时图片数据已经过通义千问VL大模型提取描述特征,并Embedding为向量。

可以看出下图经过通义千问VL大模型提取后,文本总结为“站在海滩上的人穿着牛仔裤和绿色靴子。沙滩上有水迹覆盖。关键词:海滩、脚印、沙地、鞋子、裤子”,用文字非常形象的描述了这张图片的特征。

图:jean/n03594734_9714.JPEG

多模态量检索:以文搜图

在下面这个这个示例中,查询文本query为"棕色的狗",将query通过多模态向量模型Embedding以后,分别在image_embedding和text_embedding上进行以文搜图和以文搜文,可以得到不同的检索结果。

注意:由于大模型产出结果存在一定的随机性,本示例结果可能无法完全一致的复现。

if __name__ == "__main__":MILVUS_HOST = "c-xxxxxxxxxxxx.milvus.aliyuncs.com"MILVUS_PORT = "19530"MILVUS_TOKEN = "root:password"COLLECTION_NAME = "multimodal_search"INDEX = "IVF_FLAT" # IVF_FLAT OR HNSW# Step1:初始化Milvus客户端milvus_client = MilvusClient(MILVUS_TOKEN, MILVUS_HOST, MILVUS_PORT, INDEX, COLLECTION_NAME)DASHSCOPE_API_KEY = ""# Step2:初始化多模态Embedding模型extractor = FeatureExtractor(DASHSCOPE_API_KEY)# Step4:多模态搜索示例,以文搜图和以文搜文text_query = "棕色的狗"text_embedding = extractor(text_query, "text")text_results_1 = milvus_client.search(text_embedding, feild = 'image_embedding')logger.info(f"以文搜图查询结果: {text_results_1}")text_results_2 = milvus_client.search(text_embedding, feild = 'text_embedding')logger.info(f"以文搜文查询结果: {text_results_2}")"""
以文搜图查询结果
{'id': 457336885198973657, 'distance': 1.338853359222412, 'origin': './train/Rhodesian_ridgeback/n02087394_9675.JPEG', 'image_description': '一张小狗站在地毯上的照片。它有着棕色的毛发和蓝色的眼睛。\n关键词:小狗、地毯、眼睛、毛色、站立'}, 
{'id': 457336885198973648, 'distance': 1.3568601608276367, 'origin': './train/Rhodesian_ridgeback/n02087394_6382.JPEG', 'image_description': '这是一只棕色的猎犬,耳朵垂下,脖子上戴着项圈。它正直视前方。\n\n关键词:狗、棕色、猎犬、耳朵、项链'},
{'id': 457336885198973655, 'distance': 1.3838427066802979, 'origin': './train/Rhodesian_ridgeback/n02087394_5846.JPEG', 'image_description': '两只小狗在毛毯上玩耍。一只狗躺在另一只上面,背景中有一个玩具熊。\n\n关键词:小狗、玩闹、毛毯、玩具熊、互动'}
""""""
以文搜文查询结果
[{'id': 457336885198973739, 'distance': 0.6969608068466187, 'origin': './train/mongoose/n02137549_7552.JPEG', 'image_description': '这是一张棕色的小动物的特写照片。它有着圆润的脸庞和大大的眼睛。\n\n关键词:小动物、棕毛、圆形脸、大眼、自然背景'}, 
{'id': 457336885198973648, 'distance': 0.7110348343849182, 'origin': './train/Rhodesian_ridgeback/n02087394_6382.JPEG', 'image_description': '这是一只棕色的猎犬,耳朵垂下,脖子上戴着项圈。它正直视前方。\n\n关键词:狗、棕色、猎犬、耳朵、项链'}, 
{'id': 457336885198973707, 'distance': 0.7725887298583984, 'origin': './train/lion/n02129165_19310.JPEG', 'image_description': '这是一张狮子的特写照片。它有着浓密的鬃毛和锐利的眼神。\n\n关键词:狮子、眼神、鬃毛、自然环境、野生动物'}
"""

多模态向量检索:以图搜文

在下面这个这个示例中,我们使用test中的狮子图片进行相似性检索,分别进行以图搜图和以图搜文。

图:lion/n02129165_13728.JPEG

注意:由于大模型产出结果存在一定的随机性,本示例结果可能无法完全一致的复现。

if __name__ == "__main__":MILVUS_HOST = "c-xxxxxxxxxxxx.milvus.aliyuncs.com"MILVUS_PORT = "19530"MILVUS_TOKEN = "root:password"COLLECTION_NAME = "multimodal_search"INDEX = "IVF_FLAT" # IVF_FLAT OR HNSW# Step1:初始化Milvus客户端milvus_client = MilvusClient(MILVUS_TOKEN, MILVUS_HOST, MILVUS_PORT, INDEX, COLLECTION_NAME)DASHSCOPE_API_KEY = ""# Step2:初始化多模态Embedding模型extractor = FeatureExtractor(DASHSCOPE_API_KEY)# Step5:多模态搜索示例,以图搜图和以图搜文image_query_path = "./test/lion/n02129165_13728.JPEG"image_embedding = extractor(image_query_path, "image")image_results_1 = milvus_client.search(image_embedding, feild = 'image_embedding')logger.info(f"以图搜图查询结果: {image_results_1}")image_results_2 = milvus_client.search(image_embedding, feild = 'text_embedding')logger.info(f"以图搜文查询结果: {image_results_2}")"""
以图搜图查询结果
{'id': 457336885198973702, 'distance': 0.23892249166965485, 'origin': './train/lion/n02129165_19953.JPEG', 'image_description': '这是一只雄壮的狮子站在岩石旁,背景是树木和灌木丛。阳光洒在它的身上。\n\n关键词:狮子、岩石、森林、阳光、野性'},
{'id': 457336885198973704, 'distance': 0.4113130569458008, 'origin': './train/lion/n02129165_1142.JPEG', 'image_description': '一只狮子在茂密的绿色植物中休息。背景是竹子和树木。\n\n关键词:狮子、草地、绿植、树干、自然环境'}, 
{'id': 457336885198973699, 'distance': 0.5206397175788879, 'origin': './train/lion/n02129165_16.JPEG', 'image_description': '图中是一对狮子在草地上站立。雄狮鬃毛浓密,雌狮则显得更为瘦弱。\n\n关键词:狮子、草地、雄性、雌性、自然环境'}
""""""
以图搜文查询结果
{'id': 457336885198973704, 'distance': 1.0935896635055542, 'origin': './train/lion/n02129165_1142.JPEG', 'image_description': '一只狮子在茂密的绿色植物中休息。背景是竹子和树木。\n\n关键词:狮子、草地、绿植、树干、自然环境'}, 
{'id': 457336885198973702, 'distance': 1.2102885246276855, 'origin': './train/lion/n02129165_19953.JPEG', 'image_description': '这是一只雄壮的狮子站在岩石旁,背景是树木和灌木丛。阳光洒在它的身上。\n\n关键词:狮子、岩石、森林、阳光、野性'},
{'id': 457336885198973707, 'distance': 1.2725986242294312, 'origin': './train/lion/n02129165_19310.JPEG', 'image_description': '这是一张狮子的特写照片。它有着浓密的鬃毛和锐利的眼神。\n\n关键词:狮子、眼神、鬃毛、自然环境、野生动物'}
"""

import base64
import csv
import dashscope
import os
import pandas as pd
import sys
import time
from tqdm import tqdm
from pymilvus import (connections,FieldSchema,CollectionSchema,DataType,Collection,MilvusException,utility
)
from http import HTTPStatus
import logginglogging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)class FeatureExtractor:def __init__(self):self._api_key = os.getenv("DASHSCOPE_API_KEY")  # 使用环境变量存储API密钥def __call__(self, input_data, input_type):if input_type not in ("image", "text"):raise ValueError("Invalid input type. Must be 'image' or 'text'.")try:if input_type == "image":_, ext = os.path.splitext(input_data)image_format = ext.lstrip(".").lower()with open(input_data, "rb") as image_file:base64_image = base64.b64encode(image_file.read()).decode("utf-8")input_data = f"data:image/{image_format};base64,{base64_image}"payload = [{"image": input_data}]else:payload = [{"text": input_data}]resp = dashscope.MultiModalEmbedding.call(model="multimodal-embedding-v1",input=payload,api_key=self._api_key,)if resp.status_code == HTTPStatus.OK:return resp.output["embeddings"][0]["embedding"]else:raise RuntimeError(f"API调用失败,状态码: {resp.status_code}, 错误信息: {resp.message}")except Exception as e:logger.error(f"处理失败: {str(e)}")raiseclass MilvusClient:def __init__(self):self._token = os.getenv("MILVUS_TOKEN")self._host = os.getenv("MILVUS_HOST")self._port = os.getenv("MILVUS_PORT", "19530")self._collection_name = "multimodal_search"self._connect()self._create_collection_if_not_exists()def _connect(self):try:connections.connect(alias="default", host=self._host, port=self._port, token=self._token)logger.info("Connected to Milvus successfully.")except Exception as e:logger.error(f"连接Milvus失败: {str(e)}")sys.exit(1)def _collection_exists(self):return self._collection_name in utility.list_collections()def _create_index(self):index_params = {"index_type": "IVF_FLAT","params": {"nlist": 1024},"metric_type": "L2",}self._collection.create_index("embedding", index_params)logger.info("Index created successfully.")def _create_collection_if_not_exists(self):try:if not self._collection_exists():fields = [FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1024),FieldSchema(name="origin", dtype=DataType.VARCHAR, max_length=512),]schema = CollectionSchema(fields)self._collection = Collection(self._collection_name, schema)self._create_index()logger.info("Collection created successfully.")else:self._collection = Collection(self._collection_name)logger.info("Collection already exists.")except Exception as e:logger.error(f"创建或加载集合失败: {str(e)}")sys.exit(1)def insert(self, data):try:self._collection.insert(data)self._collection.load()logger.info("数据插入并加载成功.")except MilvusException as e:logger.error(f"插入数据失败: {str(e)}")raisedef search(self, query_embedding, limit=10):try:result = self._collection.search(data=[query_embedding],anns_field="embedding",param={"metric_type": "L2", "params": {"nprobe": 10}},limit=limit,output_fields=["origin"],)return [{"id": hit.id, "distance": hit.distance, "origin": hit.origin} for hit in result[0]]except Exception as e:logger.error(f"搜索失败: {str(e)}")return Nonedef load_image_embeddings(extractor, csv_path):df = pd.read_csv(csv_path)image_embeddings = {}for image_path in tqdm(df["path"].tolist(), desc="生成图像嵌入"):try:image_embeddings[image_path] = extractor(image_path, "image")time.sleep(0.6)  # 控制API调用频率except Exception as e:logger.warning(f"处理{image_path}失败,已跳过: {str(e)}")return [{"origin": k, "embedding": v} for k, v in image_embeddings.items()]def main():# 初始化Milvus客户端milvus_client = MilvusClient()# 初始化特征提取器extractor = FeatureExtractor()## 1. 将图片数据集Embedding后插入到Milvusembeddings = load_image_embeddings(extractor, "reverse_image_search.csv")milvus_client.insert(embeddings)# 2. 执行搜索测试# 示例:以文搜图text_query = "木质折叠椅"text_embedding = extractor(text_query, "text")text_results = milvus_client.search(text_embedding)logger.info(f"以文搜图查询结果: {text_results}")# 示例:以图搜图image_query_path = "./test/Airedale/n02096051_4092.JPEG"image_embedding = extractor(image_query_path, "image")image_results = milvus_client.search(image_embedding)logger.info(f"以图搜图查询结果: {image_results}")if __name__ == "__main__":main()

相关文章:

通过阿里云Milvus与通义千问VL大模型,快速实现多模态搜索

本文主要演示了如何使用阿里云向量检索服务Milvus版与通义千问VL大模型,提取图片特征,并使用多模态Embedding模型,快速实现多模态搜索。 基于灵积(Dashscope)模型服务上的通义千问 API以及Embedding API来接入图片、文…...

React 与 Vue:两大前端框架的深度对比

在前端开发领域,React 和 Vue 无疑是当下最受欢迎的两大框架。它们各自拥有独特的优势和特点,吸引了大量开发者。无论是初学者还是经验丰富的工程师,选择 React 还是 Vue 都是一个常见的问题。本文将从多个角度对 React 和 Vue 进行对比&…...

OpenFeign和Gateway

OpenFeign和Gateway 一.OpenFeign介绍二.快速上手1.引入依赖2.开启openfeign的功能3.编写客户端4.修改远程调用代码5.测试 三.OpenFeign参数传递1.传递单个参数2.多个参数、传递对象和传递JSON字符串3.最佳方式写代码继承的方式抽取的方式 四.部署OpenFeign五.统一服务入口-Gat…...

openwrt作旁路由时的几个常见问题 openwrt作为旁路由配置zerotier 图文讲解

1 先看openwrt时间,一定要保证时间和浏览器和服务器是一致的,不然无法更新 2 openwrt设置旁路由前先测试下,路由器能否ping通主路由,是否能够连接外网,好多旁路由设置完了,发现还不能远程好多就是旁路由本…...

ai如何赋能艺术教育

在数字化浪潮席卷全球的今天,人工智能(AI)作为第四次工业革命的核心驱动力,正以前所未有的速度重塑教育生态。艺术教育领域作为培养创造力、批判性思维与跨文化理解力的关键阵地,正经历着AI技术带来的深刻变革。本文将从技术赋能、教育范式革新、全球化协作三个维度,探讨…...

NocoBase 本周更新汇总:联动规则条件左侧支持变量

原文链接:https://www.nocobase.com/cn/blog/weekly-updates-20250424。 汇总一周产品更新日志,最新发布可以前往我们的博客查看。 NocoBase 目前更新包括的版本更新包括三个分支:main ,next和 develop。 main :截止…...

协作开发攻略:Git全面使用指南 — 第二部分 高级技巧与最佳实践

协作开发攻略:Git全面使用指南 — 第二部分 高级技巧与最佳实践 Git 是一种分布式版本控制系统,用于跟踪文件和目录的变更。它能帮助开发者有效管理代码版本,支持多人协作开发,方便代码合并与冲突解决,广泛应用于软件开…...

sass 变量

基本使用 如果分配给变量的值后面添加了 !default 标志 ,这意味着该变量如果已经赋值,那么它不会被重新赋值,但是,如果它尚未赋值,那么它会被赋予新的给定值。 如果在此之前变量已经赋值,那就不使用默认值…...

多级缓存架构深度解析:从设计原理到生产实践

多级缓存架构深度解析:从设计原理到生产实践 一、多级缓存架构核心定位与设计原则 1. 架构分层与角色定位 多级缓存通过分层存储、流量削峰、数据分级实现性能与成本的平衡,典型三层架构如下: 层级代表组件存储介质数据特征命中目标成本级…...

(51单片机)LCD展示动画(延时函数)(LLCD1602教程)

前言&#xff1a; 前面我们说过&#xff0c;之前LCD1602模块有点难&#xff0c;但是现在&#xff0c;我们通过几遍博客的学习&#xff0c;今天来讲一下LCD1602的原理 演示视频&#xff1a; LCD1602流动 源代码&#xff1a; main.c #include <STC89C5xRC.H> #include &q…...

12N60-ASEMI无人机专用功率器件12N60

编辑&#xff1a;LL 12N60-ASEMI无人机专用功率器件12N60 型号&#xff1a;12N60 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大漏源电流&#xff1a;12A 漏源击穿电压&#xff1a;600V 批号&#xff1a;最新 RDS&#xff08;ON&#xff09;Max&#xff1a;0.68…...

[Redis] Redis最佳实践

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

arm64适配系列文章-第九章-arm64环境上sentinel的部署

ARM64适配系列文章 第一章 arm64环境上kubesphere和k8s的部署 第二章 arm64环境上nfs-subdir-external-provisioner的部署 第三章 arm64环境上mariadb的部署 第四章 arm64环境上nacos的部署 第五章 arm64环境上redis的部署 第六章 arm64环境上rabbitmq-management的部署 第七章…...

3dmax模型怎么处理3dtiles,制作制作B3DM格式文件

1咱们先打3dmax&#xff0c;或su或者其他软件建模型 2记住面一定一定要少&#xff0c;面一定不能多&#xff0c;也不要是VR材质&#xff0c;可以用插件一键处理 3导出fbx 4使用cesium把fbx转换 5这里可以坐标&#xff0c;因为要对地图位置 6转换出来了&#xff0c;3dtiles格式…...

雪花算法生成int64,在前端js的精度问题

1.问题背景 后端对视频生成唯一性id&#xff0c;在发送评论阶段&#xff0c;由于后端接收的json数据格式&#xff0c;设置videoId为int64。前端于是使用js的Number函数&#xff0c;进行字符串转换为数字&#xff0c;由于不清楚js的精度范围&#xff0c;产生了携带的videoId变化…...

软件测试报告包括哪些内容?可出专业软件测试方案的测评机构推荐

随着信息技术的快速发展&#xff0c;软件质量已经成为决定企业竞争力的重要因素之一。软件测试作为保障软件质量的关键环节&#xff0c;其成果汇总形成的“软件测试报告”在项目生命周期中扮演着重要角色。 软件测试报告就是用来反映测试工作全貌的报告。从测试准备、过程、结…...

dockercompose文件仓库

mysql version: 3 # 使用docker-compose的版本&#xff0c;根据需要可以调整# 创建数据目录 # mkdir -p /home/docker/mysql/mysql_data # mkdir -p /home/docker/mysql/mysql_logs # 给予适当的权限&#xff08;确保MySQL容器可以读写这些目录&#xff09; # chmod 777 /ho…...

Docker 的基本概念和优势以及在应用程序开发中的实际应用

Docker 是一种开源的容器化平台,可以让开发者将应用程序及其所有依赖项打包成一个独立的容器,从而实现应用程序的快速部署和运行。下面是 Docker 的基本概念和优势: 基本概念: 容器:一个轻量级、独立的运行环境,包含应用程序及其所有依赖项。镜像:一个只读的模板,用于创…...

JavaWeb:HtmlCss

快速入门 <html><head><title>HTML快速入门</title><head><body><h1>Hello HTML</h1><img src"1.png"></img></body> </html>开发工具vscode 常见便签&样式&#xff08;新闻&#xff0…...

linux centOS7.9 No package docker-ce available

docker pull apache/apisix:3.2.2-centos Error response from daemon: missing signature key 处理方式如下&#xff1a; 问题&#xff1a;在纯净机里安装docker时报错No package docker-ce available。 解决办法&#xff1a; 1、更新yum&#xff0c;使用yum -y upgrade&#…...

机器学习(8)——主成分分析

文章目录 1. 主成分分析介绍2. 核心思想3. 数学基础4. 算法步骤4.1. 数据标准化&#xff1a;4.2. 计算协方差矩阵&#xff1a;4.3. 特征分解&#xff1a;4.4. 选择主成分&#xff1a;4.5 降维&#xff1a; 5. 关键参数6. 优缺点7. 改进变种8. 应用场景9. Python示例10. 数学推导…...

使用深度 Q 学习解决Lunar lander问题

使用深度 Q 学习解决Lunar lander问题 0. 前言1. 使用深度 Q 网络解决 Atari 游戏2. 定义环境3. 解决 Lunar lander 问题相关链接 0. 前言 深度 Q 学习模型只需观察状态作为输入就能够解决经典 Atari 游戏&#xff0c;这是一个重大突破&#xff0c;从那时起&#xff0c;深度强…...

centos7使用yum快速安装最新版本Jenkins-2.462.3

Jenkins支持多种安装方式&#xff1a;yum安装、war包安装、Docker安装等。 官方下载地址&#xff1a;https://www.jenkins.io/zh/download 本次实验使用yum方式安装Jenkins LTS长期支持版&#xff0c;版本为 2.462.3。 一、Jenkins基础环境的安装与配置 1.1&#xff1a;基本…...

Bean的生命周期

1.实例化Bean&#xff08;通过BeanDefinition反射调用无参构造创建对象&#xff0c;如果没有无参构造&#xff0c;需要指定唯一构造方法&#xff09; 2.给Bean的属性set()赋值 3.检查Bean是否实现了Aware相关接口&#xff0c;实现的话则执行方法 Aware接口&#xff1a;空接口&…...

【缓存与数据库结合方案】伪从技术 vs 直接同步/MQ方案的深度对比

伪从技术 vs 直接同步/MQ方案的深度对比 直接同步修改或通过MQ消息队列也能实现类似同步功能&#xff0c;但伪从技术&#xff08;通过消费binlog实现数据同步&#xff09;在某些场景下具有独特优势。下面我将从多个维度进行详细对比分析&#xff1a; 一、核心差异对比表 方案…...

【前端】【业务场景】【面试】在前端开发中,如何实现文件的上传与下载功能,并且处理可能出现的错误情况?

前端文件上传与下载攻略 本文目标&#xff1a;帮你快速掌握文件上传 & 下载的核心实现方式&#xff0c;并在常见出错场景下保持“优雅不崩溃”。 一、文件上传 1. 基础结构 <input type"file" id"fileInput" /> <button id"uploadBtn&…...

【axios取消请求】如何在token过期后取消未响应的请求

功能背景&#xff1a; 我们在实际项目中通常会遇到登录过期后会跳登录页的情况&#xff0c;回跳过程会根据接口请求的状态码判断是否登陆状态过期&#xff0c;并给出用户提示&#xff0c;如果此时存在多个请求接口同时调用&#xff0c;就会同时报出多个登录过期的提示&#xf…...

【高频考点精讲】JavaScript中的组合模式:从树形结构到组件嵌套实战

📚 目录 📦 什么是组合模式?🌲 基础版:用组合模式构建一个简单的树形结构💡 举个更真实的场景:菜单组件🧠 为什么组合模式在前端特别重要?🔨 实战案例:组件嵌套组合 + 权限控制🧩 组合模式的延伸用法:搭建 UI DSL 引擎🧪 面试题时间(欢迎评论区作答)组…...

《仙剑奇侠传二》游戏秘籍

无限冥纸&#xff1a;在丰都城&#xff0c;点击特定的小猫&#xff0c;它会给你五张冥纸&#xff0c;再次点击还会再给五张&#xff0c;可循环获取。无限使用虎煞技能&#xff1a;学会 “虎啸风声” 技能后&#xff0c;将虎煞之力值设置为 16&#xff0c;在战斗中持续使用该技能…...

AWS 中国区 CloudFront SSL 证书到期更换实战指南

适用场景: AWS 中国区(宁夏区域 cn-northwest-1 或北京区域 cn-north-1)CloudFront 分配的 SSL 证书到期后无缝替换,域名主体为 domain.cn。 背景与痛点 当 CloudFront 使用的 SSL 证书即将到期时,需手动替换新证书以避免服务中断。由于 AWS 中国区 不支持 ACM 证书,必须…...

【2025A卷】华为OD机试九日集训第3期 - 按算法分类,由易到难,提升编程能力和解题技巧,从而提高机试通过率(Python/JS/C/C++)

目录 一、适合人群二、本期训练时间三、如何参加四、数据结构与算法大纲五、华为OD九日集训第3期第1天、逻辑分析第2天、逻辑分析第3天、双指针第4天、双指针第5天、数据结构map第6天、栈第7天、二叉树第8天、贪心算法第9天、二分查找 六、集训总结国内直接使用最新o3、o4-mini…...

MacOS上如何运行内网穿透详细教程

本文以市面常见、好用的内网穿透为例&#xff0c;一款为开源内网穿透工具Frp;另一款为国产新锐软件ZeroNews。 一、Frp&#xff08;开源工作、使用自由&#xff09; 1. 下载 FRP 访问 FRP 的 GitHub 发布页&#xff1a; https://github.com/fatedier/frp/releases 选择适合 …...

第55讲:农业人工智能的跨学科融合与社会影响——构建更加可持续、包容的农业社会

目录 一、农业人工智能的多维融合:科技与社会的桥梁 1. 技术与社会:解决现代农业中的不平等 2. AI与伦理:塑造道德规范与社会责任 3. AI与政策:推动农业政策的科学决策与智能执行 二、AI与农业未来社会的构建:更绿色、更智能、更包容 1. 推动农业可持续发展:绿色农…...

JVM性能优化之老年代参数设置

一、引言 咱们书接上回&#xff0c;上篇文章主要讲解了年轻代参数设置&#xff0c;如果对这一部分还不清楚的建议先去看一下&#xff08;年轻代参数设置&#xff09;&#xff0c;本文主要为大家介绍老年代参数的设置&#xff0c;掌握好jvm参数的设置是一个高级开发人人员必备的…...

在 Ubuntu 环境为 Elasticsearch 引入 `icu_tokenizer

1. 为什么需要 ICU 分析插件 Elasticsearch 默认的 standard tokenizer 遵循 UAX #29 规则&#xff0c;但在 CJK&#xff08;中、日、韩&#xff09;等亚洲语言上仅能按字符切分&#xff0c;无法识别词边界&#xff1b;对包含重音符号、大小写或多脚本混排的文本也缺乏统一归一…...

JMeter 安装及使用 [软件测试工具]

目录 JMeter 1. JMeter 安装 1.1 点击官网下载: JMeter官网下载 1.2 下载后解压即可 1.3 打开 JMeter 1.3.1 方式一: 点击对应程序打开 1.3.2 方式二: 命令行启动 1.4 关闭 JMeter 2. JMeter 基础配置 2.1 修改字体为简体中文 2.2 添加拓展插件 2.2.1 下载其他监听器…...

Unity 资源合理性检测

一&#xff1a;表格过度配置&#xff0c;表格资源是否在工程中存在&#xff0c;并输出不存在的资源 import pandas as pd import glob import osassets [] count 0# 遍历configs文件夹下所有xlsx文件 for file_path in glob.glob(configs/*.xlsx):count 1try:sheets pd.re…...

vue-study(1)

黑马智数项目 黑马智数是一个数字化园区管理项目&#xff0c;该项目后台可以在线管理园区内的楼宇、企业、车辆和一体杆等资源&#xff0c;可视化大屏通过园区3D模型实时展示园区概况。通过该项目能学到如何用qiankun搭建微前端架构、用Echarts进行数据可视化、以及前沿的3D模…...

XS5032:高性能3DNR+HDR ISP-TX 2K芯片

爱芯元智 XS5032&#xff1a;高性能3DNRHDR ISP-TX 2K芯片 视频输入 支持MIPI接口&#xff0c;4lane&#xff0c;Max.1.5Gbps/lane 支持Sensor并口&#xff08;DVP&#xff09; 视频分辨率 支持多种同轴高清制式和标清制式&#xff0c;包括&#xff1a; 960H25/30fps&…...

[原创](现代Delphi 12指南):[macOS 64bit App开发]:如何使用NSString类型字符串?

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

TDengine 流计算引擎设计

流计算架构 TDengine 流计算的架构如下图所示。当用户输入用于创建流的 SQL 后&#xff0c;首先&#xff0c;该 SQL 将在客户端进行解析&#xff0c;并生成流计算执行所需的逻辑执行计划及其相关属性信息。其次&#xff0c;客户端将这些信息发送至 mnode。mnode 利用来自数据源…...

扩展中国剩余定理

中国剩余定理 中国剩余定理 考虑一组模线性同余方程&#xff1a; { x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) . . . x ≡ a k ( m o d m k ) \begin{cases} x\equiv a_1\pmod{m1} \\ x\equiv a_2\pmod{m2}\\ .\\ .\\ .\\ x\equiv a_k\pmod{mk}\\ \end{cases} ⎩ ⎨ ⎧…...

git检查提交分支和package.json的version版本是否一致

这里写自定义目录标题 一、核心实现步骤‌1.安装必要依赖‌2.初始化 Husky‌3.创建校验脚本‌4.配置 lint-staged‌5.更新 Husky 钩子‌ 三、工作流程说明‌四、注意事项‌ 以下是基于 Git Hooks 的完整解决方案&#xff0c;通过 husky 和自定义脚本实现分支名与版本号一致性校…...

Git 详细使用说明文档(适合小白)

Git 详细使用说明文档&#xff08;适合小白&#xff09; 1. 什么是 Git&#xff1f; Git 是一个版本控制系统&#xff0c;帮助你管理和跟踪代码的变更。无论是个人项目还是团队协作&#xff0c;Git 都能帮助你记录代码的历史版本&#xff0c;方便回溯和协作。 2. 安装 Git …...

【嵌入式系统设计师(软考中级)】第二章:嵌入式系统硬件基础知识(2)

文章目录 3.嵌入式系统的存储体系3.1 存储系统的层次结构3.2 内存管理单元&#xff08;MMU&#xff09;3.3 RAM和ROM的种类3.3.1 RAM类型对比3.3.2 ROM类型对比 3.4 高速缓存&#xff08;Cache&#xff09;3.5 其他存储设备3.5.1 新型存储技术3.5.2 外存接口技术 3.嵌入式系统的…...

rk3588 驱动开发(三)第五章 新字符设备驱动实验

register_chrdev 和 unregister_chrdev 这两个函数是老版本驱动使用的函数&#xff0c;现在新的字符设备驱动已经不再使用这两个函数&#xff0c;而是使用 Linux 内核推荐的新字符设备驱动 API 函数。本节我们就来学习一下如何编写新字符设备驱动&#xff0c;并且在驱动模块加载…...

文件上传--WAF绕过干货

本文主要内容 绕过WAF上传文件 -- 安全狗 -- 宝塔 Burp抓包解析 #上传参数名解析&#xff1a;明确哪些东西能修改? Content-Disposition&#xff1a;—般可更改 name&#xff1a;表单参数值&#xff0c;不能更改 filename&#xff1a;文件名&#xff…...

BERT BERT

BERT ***** 2020年3月11日更新&#xff1a;更小的BERT模型 ***** 这是在《深阅读的学生学得更好&#xff1a;预训练紧凑模型的重要性》&#xff08;arXiv:1908.08962&#xff09;中提到的24种较小规模的英文未分词BERT模型的发布。 我们已经证明&#xff0c;标准的BERT架构和…...

Kotlin Multiplatform--02:项目结构进阶

Kotlin Multiplatform--02&#xff1a;项目结构进阶 引言正文 引言 在上一章中&#xff0c;我们对 Kotlin Multiplatform 项目有了基本的了解&#xff0c;已经可以进行开发了。但我们只是使用了系统默认的项目结构。本章介绍了如何进行更复杂的项目结构管理。 正文 在上一章中&…...

【ES实战】Elasticsearch中模糊匹配类的查询

Elasticsearch中模糊匹配类的查询 文章目录 Elasticsearch中模糊匹配类的查询通配符查询前缀匹配查询正则匹配查询标准的正则操作特殊运算符操作 模糊化查询Fuzziness text类型同时配置keyword类型 Elasticsearch中模糊类查询主要有以下 Wildcard Query&#xff1a;通配符查询P…...