Volcano 进阶实战:网络拓扑与负载感知调度的深度协同

news2026/3/16 4:37:06
1. 从单打独斗到并肩作战为什么我们需要协同调度大家好我是老张在AI基础设施这块摸爬滚打了十来年亲眼看着集群规模从几十台服务器膨胀到成千上万台。早期做模型训练调度器只管一件事把任务塞到有资源的机器上就完事了。那时候网络简单任务也相对独立这种“填鸭式”调度还能应付。但现在的AI训练尤其是动辄千亿参数的大模型玩法完全变了。模型并行、数据并行、流水线并行这些技术让一个训练任务像一张大网撒在几十甚至上百个节点上。这些节点之间可不是老死不相往来的它们每分每秒都在疯狂地交换梯度、同步参数。这时候网络就成了命门。我遇到过最头疼的情况是调度器把需要频繁通信的两个Pod一个扔在了北京机房的A机架另一个扔在了上海机房的B机架。好家伙训练速度直接掉到地板上宝贵的GPU算力全在等网络钱烧得我心都在滴血。这就是网络拓扑感知调度要解决的问题它像个精明的“房产中介”清楚知道集群里每台服务器的“地理位置”在哪个机架、连到哪台交换机优先把需要密切往来的任务安排成“邻居”甚至“室友”最大限度地减少通信跳数降低延迟。那是不是有了这个“房产中介”就高枕无忧了呢也不是。集群是活的负载时刻在变。想象一下你精心安排了一组Pod在同一个机架内网络通信是快了但这个机架的某个节点突然被一个高优先级的推理任务占满了CPU和内存。结果就是网络链路是最优的但计算资源成了瓶颈任务照样卡住。或者某个节点因为硬件老化或异常进程负载异常升高成为整个训练任务的“短板”。这就需要负载感知调度出场了。它像个时刻巡逻的“物业管家”实时监控每个节点的CPU、内存、GPU利用率等指标。一旦发现某个节点压力过大或者集群负载严重不均衡它就会出手干预可能会把一些不那么紧急的任务“请”出去驱逐让更重要的任务能平稳运行。所以你发现了吗网络拓扑优化是“静态”或“半静态”的布局艺术追求的是通信效率的极致而负载感知是“动态”的平衡术追求的是资源利用的稳定与公平。在真实的、动态变化的生产环境中尤其是长周期的AI训练任务里两者缺一不可。只讲拓扑可能陷入局部最优被突发的负载打垮只讲负载可能牺牲了至关重要的通信性能训练效率上不去。今天我就结合自己的实战经验跟大家聊聊怎么让这两位“高手”深度协同真正实现112的效果。2. 打好地基网络拓扑感知调度的实战配置在谈协同之前我们得先把两位“高手”各自的本事摸透。咱们先来看看网络拓扑感知调度在Volcano里是怎么落地的。这部分的核心理念是将物理的网络拓扑结构映射成Kubernetes能理解的抽象标签和层级关系。2.1 理解网络拓扑的层次模型Volcano使用了一个叫做HyperNode的概念来抽象网络拓扑。你可以把它理解为一个“容器”里面可以装真实的物理节点Node也可以装其他更小的HyperNode从而构建出一个树状的层次结构。通常我们会根据数据中心的实际结构来定义层级Tier。举个例子一个典型的层级可能是Tier 0 (最底层): 单个服务器节点Node。这是最细的粒度。Tier 1: 机架Rack。一个机架内包含多个服务器它们通常通过架顶交换机ToR Switch互联延迟极低。Tier 2: 聚合交换机Aggregation Switch层面。多个机架连接到同一台聚合交换机。Tier 3: 核心交换机Core Switch或机房层面。这是更大的范围。通信成本随着层级的上升而增加。同一个机架Tier 1内的两个Pod通信比跨了核心交换机Tier 3的两个Pod要快得多。我们的目标就是让需要频繁通信的Pod尽可能待在低的、相同的层级里。2.2 动手构建你的集群拓扑图理论说完了咱们直接上实操。假设我们有一个8个Worker节点的集群主机名从te1到te8。我们模拟一个简单的拓扑两个汇聚交换机s0-s1, s0-s2每个下面挂两个机架每个机架有两台服务器。第一步给节点打上机架标签。这步相当于给每台服务器贴上“门牌号”。# 将te1, te2划分到机架 s0-s1-rack-1 kubectl label node te1 volcano.sh/racks0-s1-rack-1 --overwrite kubectl label node te2 volcano.sh/racks0-s1-rack-1 --overwrite # 将te3, te4划分到机架 s0-s1-rack-2 kubectl label node te3 volcano.sh/racks0-s1-rack-2 --overwrite kubectl label node te4 volcano.sh/racks0-s1-rack-2 --overwrite # 将te5, te6划分到机架 s0-s2-rack-3 kubectl label node te5 volcano.sh/racks0-s2-rack-3 --overwrite kubectl label node te6 volcano.sh/racks0-s2-rack-3 --overwrite # 将te7, te8划分到机架 s0-s2-rack-4 kubectl label node te7 volcano.sh/racks0-s2-rack-4 --overwrite kubectl label node te8 volcano.sh/racks0-s2-rack-4 --overwrite第二步定义HyperNode构建层级树。这是最关键的一步我们用YAML来声明层级关系。我们先定义最底层的机架级HyperNodeTier 1。# 保存为 hypernode-rack.yaml apiVersion: topology.volcano.sh/v1alpha1 kind: HyperNode metadata: name: s0-s1-rack-1 spec: tier: 1 members: - type: Node selector: exactMatch: name: te1 - type: Node selector: exactMatch: name: te2 --- apiVersion: topology.volcano.sh/v1alpha1 kind: HyperNode metadata: name: s0-s1-rack-2 spec: tier: 1 members: - type: Node selector: exactMatch: name: te3 - type: Node selector: exactMatch: name: te4 --- # 类似地定义 s0-s2-rack-3 和 s0-s2-rack-4包含 te5,te6 和 te7,te8应用这个配置kubectl apply -f hypernode-rack.yaml。接下来定义汇聚交换机层级的HyperNodeTier 2它的成员是下层的机架HyperNode。# 保存为 hypernode-aggregation.yaml apiVersion: topology.volcano.sh/v1alpha1 kind: HyperNode metadata: name: s0-s1 spec: tier: 2 members: - type: HyperNode selector: exactMatch: name: s0-s1-rack-1 - type: HyperNode selector: exactMatch: name: s0-s1-rack-2 --- apiVersion: topology.volcano.sh/v1alpha1 kind: HyperNode metadata: name: s0-s2 spec: tier: 2 members: - type: HyperNode selector: exactMatch: name: s0-s2-rack-3 - type: HyperNode selector: exactMatch: name: s0-s2-rack-4最后定义最顶层的核心层HyperNodeTier 3比如代表整个集群或一个机房。# 保存为 hypernode-core.yaml apiVersion: topology.volcano.sh/v1alpha1 kind: HyperNode metadata: name: s0 spec: tier: 3 members: - type: HyperNode selector: exactMatch: name: s0-s1 - type: HyperNode selector: exactMatch: name: s0-s2依次应用这些文件一个清晰的树形拓扑就在Volcano中建立起来了。你可以通过kubectl get hypernode查看所有拓扑节点。2.3 硬约束与软偏好调度策略的选择拓扑建好了怎么用呢在提交Volcano Job时可以通过networkTopology字段来指定调度策略。这里有两个核心模式hard和soft。hard模式严格约束这是最强硬的指令。比如你设置highestTierAllowed: 2意味着调度器会竭尽全力让这个Job的所有Pod都调度在Tier 2及以下的同一个子树内。对于上面例子就是要求所有Pod要么都在s0-s1下面包含rack-1和rack-2要么都在s0-s2下面。如果当前资源不满足这个严格条件即使有其他空闲节点任务也会一直等待Pending。这非常适合对网络延迟极度敏感的同步训练阶段。apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: ai-training-hard spec: schedulerName: volcano minAvailable: 4 networkTopology: mode: hard highestTierAllowed: 2 # 严格限制在同一个汇聚交换机下 tasks: - name: trainer replicas: 4 template: spec: containers: - name: main image: your-training-image:latest resources: requests: cpu: 8 memory: 32Gi nvidia.com/gpu: 1soft模式最佳努力这是一种更灵活的策略。调度器会优先考虑将Pod放在更低的、更紧凑的拓扑层级中但如果做不到比如目标机架资源不足它也会放宽条件调度到更高层级的节点上保证任务能尽快运行起来而不是无限等待。这种模式适用于对网络有一定要求但更强调任务启动速度和资源利用率的场景比如一些异步训练或数据预处理任务。在实际生产中我通常会根据训练任务的不同阶段混合使用。比如在核心的参数同步阶段使用hard模式确保通信效率在数据加载或模型保存阶段使用soft模式快速利用起空闲资源。3. 引入动态平衡负载感知调度的关键作用网络拓扑布局好了任务也跑起来了是不是就万事大吉了远着呢。集群环境是动态的负载波动是常态。我曾经部署了一个“完美”拓扑绑定的训练任务运行几小时后某个节点上被意外调度了一个高优先级的实时服务CPU被抢占到90%以上导致该节点上的训练进程异常缓慢拖累了整个训练迭代的速度。这就是静态拓扑调度无法解决的问题需要负载感知调度来动态纠偏。Volcano的负载感知能力主要通过volcano-descheduler这个组件来实现。它不是替代原有的调度器而是一个“再调度器”周期性地检查集群状态根据策略驱逐一些Pod触发它们重新调度以达到更均衡的负载状态。3.1 部署监控与负载感知组件负载感知的前提是能准确感知负载。所以我们需要一套监控系统来采集节点指标。通常选择metrics-server和Prometheus。安装 metrics-server用于基础资源监控kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml # 如果遇到TLS证书问题可能需要修改部署在metrics-server的容器参数中添加 --kubelet-insecure-tls安装 Prometheus用于更丰富的指标查询helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm upgrade --install prometheus prometheus-community/prometheus -n kube-system \ --set server.persistentVolume.enabledfalse \ --set alertmanager.enabledfalse安装 volcano-deschedulerkubectl apply -f https://raw.githubusercontent.com/volcano-sh/descheduler/refs/heads/main/installer/volcano-descheduler-development.yaml3.2 配置负载感知驱逐策略volcano-descheduler的行为由一个Policy配置文件控制。我们需要创建一个ConfigMap来定义负载感知的策略。下面是一个典型的配置# 保存为 descheduler-policy.yaml apiVersion: v1 kind: ConfigMap metadata: name: volcano-descheduler namespace: volcano-system data: policy.yaml: | apiVersion: descheduler/v1alpha2 kind: DeschedulerPolicy profiles: - name: kube-system pluginConfig: - args: ignorePvcPods: true nodeFit: true priorityThreshold: value: 10000 name: DefaultEvictor - args: evictableNamespaces: exclude: - default include: [] metrics: address: http://prometheus-server.kube-system.svc.cluster.local:80 type: Prometheus targetThresholds: cpu: 80 memory: 85 thresholds: cpu: 30 memory: 30 name: LoadAware plugins: balance: enabled: - LoadAware这个配置有几个关键参数我解释一下priorityThreshold: 值为10000。意思是只有优先级PriorityClass低于10000的Pod才会被考虑驱逐。这是为了保护高优先级任务如在线服务不被低优先级任务如离线训练干扰。metrics: 指定了Prometheus的地址descheduler会从这里查询节点的CPU/内存使用率。targetThresholds: 定义了节点的“高负载”阈值。当节点的CPU使用率持续超过80%或内存使用率超过85%时该节点就被认定为负载过高需要被“减负”。thresholds: 定义了集群的“不均衡”阈值。这是触发平衡动作的关键。假设集群平均CPU使用率是50%thresholds.cpu: 30意味着如果某个节点的CPU使用率比集群平均使用率高出30个百分点即达到80%并且同时存在节点的使用率低于平均使用率30个百分点即20%那么descheduler就会尝试将高负载节点上的某些Pod驱逐到低负载节点上。这个策略非常巧妙它不是简单地在节点超过绝对阈值就驱逐而是基于集群整体的不均衡程度来做决策避免了不必要的调度抖动。3.3 一个常见的“坑”与修复我在实测中发现了一个问题volcano-descheduler默认连接Prometheus查询节点负载的语句时间窗口设置得非常短[30s]在负载快速波动时容易误判。社区版本的查询语句也可能需要根据你的Prometheus指标名称做调整。通常我们需要修改descheduler的源码来适配。主要修改点在于pkg/descheduler/strategies/loadaware/load_aware.go文件中的Prometheus查询表达式。你需要将查询中的短时间区间如3s改为更合理的值如3m以获得更稳定的负载判断。修改后需要重新编译镜像并更新部署。这是一个需要一定动手能力的步骤但它能极大地提升负载感知的准确性。如果你不想修改源码也可以确保你的监控指标如node_cpu_seconds_total命名与descheduler代码中的查询一致。3.4 模拟测试看负载感知如何工作配置好后我们来模拟一个场景。首先创建两个优先级类别apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 1000 # 低于上面配置的10000可被驱逐 globalDefault: false description: Low priority tasks --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: high-priority value: 1000000 # 很高不会被驱逐 globalDefault: false description: High priority tasks然后在节点te3上部署一个低优先级的后台任务apiVersion: apps/v1 kind: Deployment metadata: name: low-priority-workload annotations: volcano.sh/preemptable: true # 标记为可被抢占/驱逐 spec: replicas: 3 selector: matchLabels: app: low-priority-app template: metadata: labels: app: low-priority-app spec: schedulerName: volcano priorityClassName: low-priority containers: - name: workload-container image: polinux/stress command: [stress] args: [--cpu, 1, --timeout, 3600s] resources: requests: cpu: 300m memory: 256Mi接着我们手动在te3节点上制造高负载比如运行一个压测Podkubectl run stress-pod-on-te3 --imagepolinux/stress --overrides{ apiVersion: v1, spec: { nodeSelector: { kubernetes.io/hostname: te3 }, containers: [{ name: stress, image: polinux/stress, command: [stress], args: [--cpu, 2, --vm, 1, --vm-bytes, 1G, --timeout, 600s] }] } }等待几分钟让Prometheus采集到te3的高负载数据。此时观察volcano-descheduler的日志kubectl logs -f deployment/volcano-descheduler -n volcano-system你应该能看到它检测到了不均衡并触发了对te3节点上低优先级Pod的驱逐事件。随后这些Pod会被Volcano调度器重新调度到其他负载较低的节点如te5上。通过kubectl get pod -o wide可以观察到Pod的位置发生了变化。这个过程完美诠释了负载感知的动态平衡能力它不关心初始位置只关心当前的负载状态并通过优雅的驱逐与再调度确保集群不会因局部过热而影响整体任务效率。4. 深度协同实战在AI训练全流程中配合无间前面我们分别演练了网络拓扑感知和负载感知。现在让我们把它们放到真实的AI训练场景中看看它们如何像一对默契的搭档在不同阶段发挥各自优势实现深度协同。4.1 训练初期拓扑优先快速建联在训练任务刚开始提交时集群状态通常是相对空闲和均衡的。这个阶段的首要目标是为需要频繁通信的Worker Pod组建立一个网络最优的“阵地”。协同策略此时应以网络拓扑感知调度为主导采用hard模式。在Job定义中明确指定highestTierAllowed例如设为2汇聚交换机层。调度器会严格寻找能满足所有GPU需求的、在同一个Tier 2子树下的节点组。这确保了训练任务从一开始就建立在低延迟、高带宽的通信基础上为后续高效同步打下坚实基础。负载感知的角色在这个阶段负载感知主要起监控和预警作用。descheduler会周期性地扫描集群但由于是新启动的任务负载通常不会立即失衡因此不会触发实际的驱逐动作。它的存在更像一个保险丝。4.2 稳定训练期动态微调应对干扰任务进入稳定迭代阶段所有Worker都在持续进行前向传播、反向传播和梯度同步。理想情况下集群应该保持稳定。但生产环境充满变数节点突发干扰某个节点上可能被调度了其他高优先级任务如紧急的模型推理导致CPU、内存或IO资源紧张进而影响该节点上训练进程的速度。硬件偶发问题GPU显存出现ECC错误、网络卡出现轻微拥塞等都会导致该节点处理速度变慢成为同步等待的“短板”。协同策略此时进入负载感知主导的动态维护阶段。volcano-descheduler根据配置的thresholds如CPU不均衡阈值30%会发现高负载节点与低负载节点的差异。它会尊重网络拓扑的约束吗这里有个精妙的设计当descheduler驱逐一个Pod后触发重新调度。新的调度请求Pod会再次经过Volcano调度器。而这个调度器依然遵循该Job最初定义的networkTopology策略这意味着即使Pod被从te3属于s0-s1-rack-2驱逐调度器重新调度时仍然会优先尝试将它分配到同一个highestTierAllowed允许范围内的、负载更低的节点上比如同属s0-s1汇聚交换机下的te4属于s0-s1-rack-2或te1属于s0-s1-rack-1。如果同拓扑域内实在没有资源根据soft或hard模式它可能会等待或放宽约束。这种协同保证了在纠正负载不均衡的同时尽可能地不破坏最初优化的网络拓扑结构。拓扑策略是“战略蓝图”负载感知是“战术微调”。4.3 弹性伸缩与任务抢占协同下的资源博弈在混部集群中高优先级的在线任务如推荐系统推理可以抢占低优先级的离线训练任务资源。这是通过Kubernetes的PriorityClass和Volcano的抢占机制实现的。协同流程一个高优先级在线任务需要资源但目标节点资源不足。Volcano调度器会寻找该节点上优先级低于该在线任务、且标记为preemptable的训练任务Pod。调度器发起抢占驱逐这些低优先级Pod。被驱逐的Pod进入Pending状态等待重新调度。重新调度时网络拓扑感知策略再次生效。调度器会为这些“无家可归”的Pod在满足其拓扑约束可能是原soft模式的节点中寻找空闲资源。如果找不到任务可能就需要等待。同时负载感知也在工作。如果因为一批Pod被集中抢占导致某个节点空出大量资源造成集群新的不均衡descheduler可能会将其他节点的一些Pod迁移过来填充资源提高整体利用率。这个过程中网络拓扑策略确保了训练任务即使在被迫迁移后仍能获得较好的通信性能负载感知策略则帮助集群在频繁的抢占和释放中快速恢复到一个相对均衡的状态避免资源碎片化。4.4 实战配置示例定义协同作业下面是一个融合了两种策略的Volcano Job示例它展示了一个训练任务如何声明自己的拓扑偏好并隐含地接受集群级的负载平衡管理。apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: distributed-llm-training annotations: # 可以添加一些自定义注解供监控或管理平台识别 training-phase: parameter-sync-intensive spec: schedulerName: volcano minAvailable: 8 queue: ai-training # 指定队列用于资源配额和优先级管理 # 网络拓扑感知配置在稳定同步阶段使用hard模式 networkTopology: mode: hard highestTierAllowed: 2 # 严格要求所有Pod在同一个汇聚交换机下 # 任务优先级影响抢占顺序 priorityClassName: medium-priority # 优先级高于low低于high tasks: - name: trainer replicas: 8 template: metadata: annotations: volcano.sh/preemptable: true # 允许被更高优先级任务抢占 spec: schedulerName: volcano affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - distributed-llm-training topologyKey: kubernetes.io/hostname containers: - name: trainer image: llm-training:latest command: [python, train.py] resources: requests: cpu: 4 memory: 32Gi nvidia.com/gpu: 1 limits: nvidia.com/gpu: 1 volumeMounts: - mountPath: /data name: training-data volumes: - name: training-data persistentVolumeClaim: claimName: shared-data-pvc在这个配置里我们看到了协同的缩影networkTopology定义了布局蓝图priorityClassName和preemptable注解定义了它在资源博弈中的角色而podAntiAffinity则是一个补充策略尽量让Pod分散在不同物理节点上避免单点故障这与拓扑感知的“聚集”策略形成互补需要根据实际情况权衡。整个任务在运行中将自动接受volcano-descheduler依据全局策略进行的负载平衡调整。要让网络拓扑感知和负载感知调度深度协同关键在于理解它们各自的作用时机和层次。拓扑调度是任务部署时的“初次分配”优化关注通信效率负载调度是运行时的“持续优化”和“自我修复”关注资源效率。通过合理的策略配置如hard/soft模式、优先级、阈值让两者在Volcano调度器的统一指挥下一静一动共同保障大规模AI训练任务在复杂动态环境中既能跑得快又能跑得稳。这其中的参数调优比如拓扑层级的划分、负载阈值的设定都需要结合具体的集群规模、网络架构和业务特点进行反复验证和调整没有银弹只有最适合自己场景的黄金组合。

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