ZenML:统一AI工作流平台,从传统ML到LLM Agent的端到端管理

news2026/5/3 7:13:26
1. 从混乱到秩序为什么我们需要一个统一的AI工作流平台如果你和我一样在AI和机器学习领域摸爬滚打了几年大概率会经历这样一个痛苦的循环项目初期一切都很美好几行Python脚本就能跑出一个惊艳的模型。但随着项目推进数据版本、实验参数、模型权重、部署环境、监控日志……这些“脏活累活”开始指数级增长。你发现自己不是在写算法而是在当“胶水工程师”疲于奔命地连接各种工具——用MLflow记录实验用Airflow调度任务用Docker打包环境用Kubeflow部署服务最后还得自己写一套监控看板。更别提当你想把传统的CV模型和最新的Agent工作流整合到一个业务里时那种跨框架、跨平台的割裂感简直让人崩溃。这就是我最初接触ZenML时的背景。当时团队正在为一个智能客服项目头疼项目里既有基于Transformer的意图分类模型传统ML也有基于LangChain的对话生成和决策AgentLLM应用。两套代码、两套部署流程、两套监控体系维护成本高得吓人。我们需要一个能将所有环节“标准化”和“自动化”的框架而不是另一个需要集成的“新工具”。ZenML的定位非常清晰一个为AI工程师打造的统一平台让你能用一套方法论和工具链管理从传统机器学习到LLM工作流再到智能体Agent的所有AI应用。它不试图取代你的PyTorch、scikit-learn或LangGraph而是作为一层“编排层”Orchestration Layer将你已有的代码、基础设施和工具无缝地串联起来形成可复现、可追踪、可部署的标准化流水线。简单说它帮你把散落各处的“乐高积木”你的模型代码、数据处理逻辑、评估脚本组装成一辆能自动运行的“乐高赛车”并且清楚地记录下每一块积木是谁、在什么时候、以什么方式拼上去的。2. ZenML核心架构解析Client-Server模型与“栈”的抽象哲学要玩转ZenML必须吃透它的两个核心设计思想Client-Server架构和Stack栈抽象。这决定了你如何开发、如何协作以及如何将实验代码推向生产。2.1 Client-Server本地开发与团队协作的基石ZenML采用经典的客户端-服务器架构这绝不是为了增加复杂度而是为了切合实际的工程场景。本地开发模式当你执行pip install zenml[server] zenml init后ZenML会在本地同时启动一个轻量级的客户端和一个服务器默认使用SQLite。所有你运行的流水线、产生的元数据如参数、指标、产物都存储在本地。这非常适合个人探索和快速原型验证所有操作都在你的笔记本上完成无需网络。生产协作模式当团队需要共享实验数据、统一部署环境或进行CI/CD集成时就需要一个独立的、中心化的ZenML Server。这个Server可以部署在你团队的Kubernetes集群、云虚拟机或托管服务上。开发者只需安装轻量级的客户端pip install zenml然后通过zenml connect --url server-url连接到远程服务器。这样所有团队成员看到的流水线历史、实验记录和可用的基础设施都是一致的。实操心得我强烈建议即使是个人项目在早期也尝试部署一个独立的ZenML Server比如用Docker Compose跑在本地。这能让你提前适应生产环境的工作流避免后期从“单机模式”迁移到“服务器模式”时遇到路径或配置上的坑。官方提供了完善的 Helm Chart 在K8s上部署非常方便。2.2 Stack栈基础设施的抽象与复用这是ZenML最精妙的设计。一个“Stack”定义了执行一个流水线所需的所有基础设施组件。它通常包含以下几类“组件”Artifact Store产物存储存放流水线运行产生的所有文件如模型文件、预处理后的数据、评估报告等。可以是本地目录、Amazon S3、Google Cloud Storage、Azure Blob等。Orchestrator编排器决定流水线步骤在何处以何种方式执行。可以是本地顺序执行local也可以是Apache Airflow、Kubeflow Pipelines、Vertex AI Pipelines等用于分布式或云上调度。Experiment Tracker实验跟踪器自动记录每次运行的超参数、指标、图表。ZenML原生支持MLflow、Weights Biases、Neptune等你无需修改代码只需在Stack中配置即可。Model Deployer模型部署器将训练好的模型部署为可调用的API服务。支持Seldon Core、KServe、TensorFlow Serving等。Step Operator步骤操作器允许你将流水线中的某个特定步骤如计算量巨大的模型训练发送到特定的硬件环境如带有GPU的Kubernetes Pod、AWS SageMaker上运行而其他步骤仍在本地执行。你可以为不同环境创建不同的Stackdev_stack: 编排器local产物存储local实验跟踪器mlflow本地。用于快速调试。staging_stack: 编排器airflowK8s集群产物存储s3://my-bucket实验跟踪器wandb。用于准生产环境测试。prod_stack: 编排器vertex_pipelines产物存储gcs://my-bucket模型部署器kserve。用于线上生产。通过zenml stack set prod_stack同一套流水线代码就能在不同的基础设施上无缝运行。这种抽象将“代码逻辑”与“运行环境”彻底解耦。# 示例注册并使用一个生产环境的Stack zenml artifact-store register s3_store --types3 --paths3://my-zenml-bucket zenml orchestrator register vertex_orch --typevertex zenml experiment-tracker register wandb_tracker --typewandb --projectmy_ai_project zenml model-deployer register kserve_deployer --typekserve zenml stack register prod_stack \ -a s3_store \ -o vertex_orch \ -e wandb_tracker \ -d kserve_deployer zenml stack set prod_stack3. 构建你的第一个端到端AI流水线从数据到可部署服务理论说再多不如动手。我们来构建一个真实的、涵盖传统ML和LLM元素的情感分析流水线。假设我们想分析用户评论先用一个文本分类模型如BERT判断情感倾向积极/消极如果是消极评论再用一个LLM如GPT生成具体的改进建议。3.1 定义步骤Steps将业务逻辑模块化步骤是ZenML流水线的基本单元用step装饰器标记。每个步骤应职责单一并明确其输入和输出。from zenml import step, pipeline from zenml.client import Client from transformers import pipeline as hf_pipeline, AutoTokenizer, AutoModelForSequenceClassification import pandas as pd from typing import Tuple, List import openai # 步骤1加载并预处理数据 step def load_and_preprocess_data(data_path: str) - pd.DataFrame: 加载原始评论数据进行基础清洗。 df pd.read_csv(data_path) # 简单的预处理去重、去空、文本清洗 df df.dropna(subset[comment]) df[comment_clean] df[comment].str.strip().str.lower() return df # 步骤2使用本地模型进行情感分类 step(enable_cacheFalse) # 禁用缓存因为模型加载是外部依赖 def sentiment_classification(df: pd.DataFrame) - Tuple[pd.DataFrame, str]: 使用预训练的BERT模型进行情感二分类。 model_name distilbert-base-uncased-finetuned-sst-2-english classifier hf_pipeline(sentiment-analysis, modelmodel_name) sentiments [] scores [] for text in df[comment_clean].tolist(): result classifier(text[:512])[0] # 模型有长度限制 sentiments.append(result[label]) scores.append(result[score]) df[sentiment] sentiments df[sentiment_score] scores # 将模型名称作为元数据输出便于追踪 return df, model_name # 步骤3对消极评论生成改进建议LLM步骤 step def generate_improvement_suggestions(df: pd.DataFrame) - pd.DataFrame: 针对消极评论调用OpenAI API生成具体的改进建议。 # 从ZenML的Secret Store中安全获取API Key client Client() secret client.get_secret(openai_secret) # 需提前通过zenml secret create创建 openai.api_key secret.secret_values[api_key] negative_reviews df[df[sentiment] NEGATIVE].copy() suggestions [] for _, row in negative_reviews.iterrows(): prompt f用户评论{row[comment_clean]}。请以客服经理的身份生成一条具体、友好、专业的回复承认问题并给出改进承诺。 try: response openai.ChatCompletion.create( modelgpt-3.5-turbo, messages[{role: user, content: prompt}], max_tokens150, temperature0.7 ) suggestion response.choices[0].message.content.strip() except Exception as e: suggestion f生成建议时出错{e} suggestions.append(suggestion) negative_reviews[ai_suggestion] suggestions # 合并回原DataFrame df df.merge(negative_reviews[[comment_clean, ai_suggestion]], oncomment_clean, howleft) return df # 步骤4评估与记录 step def evaluate_and_log(df: pd.DataFrame, model_name: str): 计算评估指标并将结果记录到实验跟踪器。 from zenml.integrations.mlflow.mlflow_step_decorator import enable_mlflow # 启用MLflow自动记录如果Stack中配置了MLflow跟踪器 enable_mlflow def _log_to_mlflow(): import mlflow # 计算一些简单指标 pos_rate (df[sentiment] POSITIVE).mean() avg_score df[sentiment_score].mean() suggestion_coverage df[ai_suggestion].notna().mean() # 记录到MLflow mlflow.log_param(model_used, model_name) mlflow.log_metric(positive_rate, pos_rate) mlflow.log_metric(avg_confidence, avg_score) mlflow.log_metric(suggestion_coverage, suggestion_coverage) # 还可以记录一个样本数据集作为artifact sample_df df.head(10) mlflow.log_table(sample_df, review_samples.json) print(f评估完成。积极评论占比{pos_rate:.2%}) _log_to_mlflow()3.2 组装流水线Pipeline编排步骤顺序流水线用pipeline装饰器定义它描述了步骤之间的依赖关系和执行顺序。pipeline(enable_cacheTrue) # 默认启用缓存输入未变的步骤会跳过执行 def sentiment_analysis_pipeline( data_path: str data/user_reviews.csv ): 端到端的情感分析与建议生成流水线。 # 执行步骤 raw_data load_and_preprocess_data(data_path) classified_data, model_used sentiment_classification(raw_data) final_data generate_improvement_suggestions(classified_data) evaluate_and_log(final_data, model_used) # 在本地运行流水线 if __name__ __main__: # 创建并运行一个流水线实例运行 run sentiment_analysis_pipeline.with_options( run_namefirst_sentiment_run_v1 )(data_pathreviews.csv) print(f流水线运行完成运行ID: {run.id})运行这段代码ZenML会自动为每个步骤创建独立的、可复现的环境通过容器化或虚拟环境。跟踪每个步骤的输入、输出、代码版本和参数。根据Stack配置将产物存储到指定位置将指标记录到MLflow/WB。如果启用了缓存且输入数据、代码未变则跳过重复计算。3.3 关键配置与材料化器Materializers你可能会问ZenML怎么知道如何保存和加载pd.DataFrame或transformers的模型对象这得益于Materializers。Materializer负责将步骤的输出对象序列化到Artifact Store并在下游步骤需要时反序列化回来。ZenML为常见类型如Pandas DataFrame, NumPy数组PIL图像提供了内置的Materializer。对于自定义对象你可以轻松编写自己的Materializer。from zenml.materializers.base_materializer import BaseMaterializer from zenml import get_step_context import joblib from typing import Type, Any class CustomModelMaterializer(BaseMaterializer): 自定义Materializer用于保存/加载scikit-learn或自定义模型。 ASSOCIATED_TYPES (object,) # 可以关联更具体的类型 def load(self, data_type: Type[Any]) - Any: 从存储路径加载模型。 model_path self.artifact.uri /model.joblib return joblib.load(model_path) def save(self, model: Any) - None: 将模型保存到存储路径。 model_path self.artifact.uri /model.joblib joblib.dump(model, model_path) # 在步骤中使用自定义Materializer step(output_materializersCustomModelMaterializer) def train_model(...) - MyModel: ...注意事项缓存Caching是ZenML提升开发效率的神器但它依赖于步骤输入、代码和参数的哈希值。如果你在步骤函数内部通过open(config.json)读取外部文件这个文件的变化不会被ZenML感知可能导致缓存失效或误用旧缓存。最佳实践是将所有外部依赖文件路径、API密钥都作为步骤的输入参数这样它们就会被纳入缓存键的计算。4. 进阶实战将LLM Agent工作流工业化传统ML流水线只是开胃菜ZenML真正的威力在于管理复杂的、有状态的LLM Agent工作流。假设我们要构建一个“竞品分析Agent”它能自动搜索网络信息、总结并生成报告。4.1 集成LangGraph与状态管理我们可以利用ZenML的step来封装LangGraph的节点Node并通过Artifact Store来持久化整个Graph的状态实现Agent的“断点续跑”和“状态回溯”。from zenml import step, pipeline, get_pipeline_context from typing import Dict, Any import asyncio from langgraph.graph import StateGraph, END from langgraph.checkpoint import MemorySaver # 假设我们已经定义好了Agent所需的工具和状态结构 # 定义Agent的状态结构Pydantic模型 from pydantic import BaseModel class ResearchState(BaseModel): query: str search_results: List[Dict] [] summary_points: List[str] [] final_report: str # 步骤1初始化Agent与Graph step(enable_cacheFalse) def setup_agent_workflow(query: str) - Dict[str, Any]: 初始化LangGraph工作流并返回初始状态。 # 构建你的LangGraph workflow StateGraph(ResearchState) # ... 这里添加各种节点Node如search_node, analyze_node, write_report_node # workflow.add_node(search, search_node) # workflow.add_edge(search, analyze) # ... # workflow.add_edge(write_report, END) # 编译Graph并使用一个检查点Checkpoint存储器 # ZenML的Artifact Store可以作为持久的Checkpoint存储后端 memory MemorySaver() # 简单示例生产环境需替换为持久化存储 app workflow.compile(checkpointermemory) # 创建初始状态 initial_state ResearchState(queryquery) config {configurable: {thread_id: research_1}} return { app: app, initial_state: initial_state.dict(), config: config } # 步骤2执行Agent工作流 step def run_agent_graph(agent_setup: Dict[str, Any]) - ResearchState: 运行Agent工作流并返回最终状态。 app agent_setup[app] initial_state agent_setup[initial_state] config agent_setup[config] # 从检查点恢复或开始新的执行 # LangGraph会处理中间状态 final_state_dict asyncio.run(app.ainvoke(initial_state, config)) final_state ResearchState(**final_state_dict) return final_state # 步骤3后处理与报告生成 step def postprocess_and_save(final_state: ResearchState): 将Agent的最终报告进行格式化并保存。 report_html f htmlbody h1竞品分析报告{final_state.query}/h1 h2关键发现/h2 ul {.join([fli{point}/li for point in final_state.summary_points])} /ul h2详细报告/h2 p{final_state.final_report}/p /body/html # 通过ZenML的上下文获取当前运行的Artifact存储路径 from zenml.client import Client client Client() run_id get_pipeline_context().pipeline_run.id # 将报告保存为ArtifactZenML会自动管理 report_path freports/{run_id}_analysis.html with open(report_path, w) as f: f.write(report_html) print(f报告已生成{report_path}) pipeline def competitive_analysis_agent_pipeline(query: str): 竞品分析Agent的完整流水线。 setup setup_agent_workflow(query) final_state run_agent_graph(setup) postprocess_and_save(final_state)通过这种方式我们将一个可能运行数小时、包含多次LLM调用的复杂Agent工作流封装成了一个可追踪、可复现、可部署的ZenML流水线。每一次运行的状态、中间结果和最终报告都被完整记录。4.2 利用MCP Server实现自然语言交互手动查看仪表盘筛选运行记录很麻烦。ZenML的MCPModel Context ProtocolServer项目让你能用自然语言与你的流水线“对话”。安装后你可以在Claude Desktop或Cursor中直接提问“上周准确率下降最多的模型是哪个”“对比一下生产环境和测试环境中‘用户流失预测’流水线的运行时间。”“重新运行昨天失败的那个数据预处理步骤。”这极大地降低了运维和排查门槛让非工程背景的团队成员也能轻松查询AI系统的状态。5. 生产部署与监控从Pipeline到Service流水线跑通了接下来是如何让模型或Agent作为服务运行起来。ZenML通过Model Deployer组件和Model Control Plane概念来处理。5.1 部署模型为在线服务假设我们想将情感分类模型部署为REST API。from zenml import step, pipeline from zenml.integrations.kserve.model_deployers import KServeModelDeployer from zenml.integrations.kserve.services import KServeDeploymentService import numpy as np step def train_and_deploy_model(...) - KServeDeploymentService: 训练模型并触发部署。 # 1. 训练模型 model train_my_model(...) # 2. 获取模型部署器 model_deployer KServeModelDeployer.get_active_model_deployer() # 3. 定义部署配置 service_config KServeDeploymentConfig( model_namesentiment-bert, predictortensorflow, # 或 sklearn, pytorch, custom replicas2, resources{requests: {cpu: 200m, memory: 512Mi}} ) # 4. 部署服务 service model_deployer.deploy_model( configservice_config, modelmodel, # 你的模型对象 # ZenML会自动处理模型打包、镜像构建、推送到仓库、K8s资源创建等 ) print(f服务已启动状态: {service.status}) print(f服务端点: {service.prediction_url}) return service pipeline def training_and_deployment_pipeline(): service train_and_deploy_model() # 可以添加一个验证步骤向刚部署的服务发送测试请求部署后你可以在ZenML Dashboard中看到所有运行中的服务进行扩缩容、更新、回滚等操作。5.2 持续训练与监控闭环生产的模型会性能衰减。你需要一个持续监控和再训练的闭环。ZenML可以轻松编排这个流程。from zenml import pipeline, step, get_pipeline_context from datetime import datetime, timedelta step def monitor_model_performance(service: KServeDeploymentService) - bool: 监控线上模型性能如果低于阈值则返回True触发重训练。 # 从服务的监控端点获取近期指标假设服务集成了Prometheus # 或从你的监控系统如Evidently, WhyLabs获取数据 current_accuracy get_current_accuracy(service) threshold 0.85 if current_accuracy threshold: print(f模型性能下降至{current_accuracy}低于阈值{threshold}触发重训练。) return True return False step def collect_new_data() - str: 收集自上次训练以来的新数据。 # 从数据湖、数据库或API收集新数据 new_data_path data/new_reviews.csv return new_data_path pipeline def continuous_training_pipeline(): 持续训练流水线监控 - 收集数据 - 重训练 - 部署。 # 假设我们通过某个步骤获取当前线上服务 current_service get_production_service() # 监控步骤 needs_retraining monitor_model_performance(current_service) # 使用条件分支只有需要重训练时才执行后续步骤 # ZenML支持基于步骤输出的条件执行 new_data collect_new_data().after(needs_retraining) # 注意实际的条件执行需要更复杂的设置或使用zenml.post_execution判断 # 这里为逻辑示意 # 更实用的模式将监控流水线设为定时运行如每天一次 # 如果检测到性能下降它可以通过ZenML的API或事件触发另一个训练流水线 # 你可以使用ZenML的Scheduler或外部的Airflow/K8s CronJob来定时运行监控流水线6. 避坑指南与最佳实践在实际项目中踩过不少坑后我总结了一些关键经验。6.1 常见问题与排查问题现象可能原因解决方案步骤缓存未命中总是重新运行1. 步骤代码或输入参数有非确定性变化如时间戳。2. 使用了未声明为输入的全局变量或外部文件。3. Materializer序列化结果不一致。1. 确保步骤是纯函数确定性输出。2. 将所有外部依赖显式声明为step的参数。3. 检查自定义Materializer的save/load方法是否可逆。连接到远程Server失败1. 网络问题或URL错误。2. 用户权限不足。3. Server版本与客户端不兼容。1. 使用zenml doctor检查连接和配置。2. 确认API密钥或用户名密码正确。3. 确保Server和Client版本匹配参考 升级指南 。流水线在K8s上运行失败1. 资源CPU/内存不足。2. 镜像拉取失败私有仓库无权限。3. 环境变量或Secret未正确注入。1. 在Stack的Orchestrator配置中调整资源请求/限制。2. 为K8s ServiceAccount配置imagePullSecrets。3. 使用zenml secret管理密钥并确认在Stack中正确关联。MLflow/WB等集成不记录数据1. Stack中未正确配置对应的Experiment Tracker。2. 步骤中未使用对应的装饰器或客户端。1.zenml stack update确保添加了正确的跟踪器组件。2. 在步骤中使用enable_mlflow或enable_wandb装饰器。自定义依赖未安装步骤运行在独立环境中未安装你的项目依赖。1. 创建requirements.txt或pyproject.toml在项目根目录。2. 运行zenml integration install your-package。3. 或使用自定义Docker镜像。6.2 性能与成本优化建议善用缓存但知其所以然缓存是双刃剑。对于数据加载、预处理等耗时步骤缓存能极大加速迭代。但对于模型训练步骤如果数据不变但你想尝试不同的超参数记得在运行命令中使用--no-cache或修改步骤参数来使缓存失效。步骤粒度要适中不要把一个包含数据加载、清洗、特征工程、训练、评估的巨型函数作为一个步骤。这不利于缓存、并行化和调试。但也不要把每个小操作都拆成步骤会增加编排开销。一个好的经验法则是一个步骤对应一个明确的、可重用的数据转换或计算任务。为生产环境选择正确的Orchestrator本地开发用local没问题但生产环境务必使用如airflow,kubeflow,vertex_pipelines等健壮的编排器它们具备重试、报警、依赖管理等企业级功能。管理好自定义镜像如果你的步骤需要特殊的系统库或复杂的Python环境建议构建自定义Docker镜像并注册到ZenML。避免每次运行都从零开始安装依赖尤其在使用云服务时这能显著减少启动延迟和成本。利用Secret管理敏感信息永远不要将API密钥、数据库密码等硬编码在代码或配置文件中。使用zenml secret create openai_key --api_keysk-...创建密钥然后在步骤中通过Client().get_secret(openai_key)安全获取。6.3 团队协作流程统一开发环境使用zenml init初始化项目后将生成的.zen目录纳入版本控制但注意排除其中的本地配置。团队成员拉取代码后只需zenml connect --url team-server-url即可连接到共享的ZenML Server和Stacks。Stack即代码将生产环境的Stack定义使用哪些云存储、哪个K8s集群等用代码管理起来如一个register_stacks.py脚本。新成员或CI/CD系统可以一键注册所有必要的基础设施。利用Pipeline Registry将成熟的流水线注册到ZenML Server (zenml pipeline register ...)。这样其他成员或自动化系统可以通过名称和版本直接调用流水线而无需接触源代码。Dashboard作为单点真相源鼓励产品经理、数据分析师通过ZenML Dashboard查看模型性能、流水线运行状态而不是向工程师索要报告。Dashboard的可视化能力是打破团队壁垒的利器。从我自己的经验来看引入ZenML的初期会有一个学习曲线需要团队适应这种“声明式”的流水线开发模式。但一旦跑通它带来的标准化、自动化和可观测性提升是巨大的。你不再需要为每一个新项目重新搭建一套MLOps架子而是可以专注于最核心的算法和业务逻辑。对于同时维护传统ML和LLM应用的中大型团队来说这种统一平台的价值尤其明显。

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