用PyTorch在超大规模下训练深度学习模型:并行策略全解析

我猜咱们每个人肯定都累坏了,天天追着 LLM 研究社区跑,感觉每天都冒出个新的最牛模型,把之前的基准都给打破了呢。要是你好奇为啥创新速度能这么快,那主要就是研究人员能够在超大规模下训练和验证模型啦,这全靠并行计算的功劳呀。

要是你还没听说过呢,5D 并行这个术语最早是 Meta AI 的论文 — The Llama 3 Herd of Models 里火起来的哦。传统上,它指的是结合数据、张量、上下文、流水线和专家并行这些技术呢。不过最近呀,又冒出了个新的玩意儿 — ZeRO (Zero Redundancy Optimizer),这可是个大杀器,通过减少分布式计算中的冗余来优化内存呢。每种技术都针对训练挑战的不同方面,它们组合起来就能搞定那些有几十亿甚至几万亿参数的模型啦。

我之前已经讲过一些比较底层的技巧啦,这些技巧能让你用 PyTorch 训练和部署模型的速度更快哦。虽然这些小贴士和小技巧能在训练时给你加分,但它们也就是加分项而已呀。要是你没有从根本上搞懂它们该在啥时候、啥地方用,那很可能就会用错地方啦。

这篇文章的重点呢,就是要给大家讲清楚模型操作的高层组织结构,还会用 PyTorch 来举些例子哦。这些并行计算的基本原则,就是现在能让模型在超大规模下(想想看,日活跃用户有几千万呢)更快迭代和部署的关键因素哦。

1. 数据并行

None

数据并行 [图片来源]

数据并行是最简单也是最常用的并行技术啦。它就是创建多个相同的模型副本,然后让每个副本在数据的不同子集上进行训练呢。在本地计算完梯度后,就会通过全归约操作(all-reduce operation)把梯度聚合起来,用来更新所有模型副本的参数呢。

当模型本身能装进单个 GPU 的内存里,但数据集太大没法按顺序处理的时候,这种方法特别管用哦。

PyTorch 通过 torch.nn.DataParalleltorch.nn.parallel.DistributedDataParallel(DDP) 模块,为数据并行提供了现成的支持呢。这其中呀,DDP 更受大家青睐,因为它在多节点设置下有更好的可扩展性和效率呢。NVIDIA 的 NeMo 框架就很好地展示了它是怎么工作的哦 —

None

数据并行示意图 [图片来源]

一个实现示例可能长这样:

import torch
import torch.nn as nn
import torch.optim as optim# 定义你的模型
model = nn.Linear(10, 1)# 用 DataParallel 包裹模型
model = nn.DataParallel(model)# 把模型移到 GPU
model = model.cuda()# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# 假数据
inputs = torch.randn(64, 10).cuda()
targets = torch.randn(64, 1).cuda()# 前向传播
outputs = model(inputs)
loss = criterion(outputs, targets)# 反向传播和优化
loss.backward()
optimizer.step()
重点收获
  • 小模型 / 大数据集 — 只有当模型能装进单个 GPU 的内存,但数据集太大时,这种方法才有效哦。
  • 模型复制 — 每个 GPU 都会保存一份相同的模型参数副本呢。
  • 小批量分割 — 输入数据会在 GPU 之间分配,确保每个设备处理一个独立的小批量数据哦。
  • 梯度同步 — 在前向和反向传播之后,梯度会在 GPU 之间同步,以保持一致性呢。
优点和注意事项
  • 简单高效 — 实现起来很简单,能很轻松地和现有的代码库集成,而且在处理大数据集时扩展性特别好哦。
  • 通信开销 — 在梯度同步时的通信开销可能会成为大规模系统的一个瓶颈呢。

2. 张量并行

None

张量并行 [图片来源]

数据并行关注的是分割数据,而 张量并行(或者叫 模型并行)则是把模型本身分散到多个设备上呢。这种方法会把大型权重矩阵和中间张量分割开来,让每个设备只负责一部分计算呢。和数据并行不同(数据并行会在每个 GPU 上复制整个模型),张量并行会把模型的层或者张量分散到不同的设备上呢。每个设备负责计算模型前向和反向传播的一部分哦。

当模型太大,没办法装进单个 GPU 的内存时,这种方法就特别有用啦,尤其是对于那些基于 Transformer 的超大模型呢。

虽然 PyTorch 没有直接提供现成的张量并行支持,但用 PyTorch 灵活的张量操作和分布式通信原语,很容易就能实现自定义的张量并行呢。不过呢,要是想要更强大的解决方案,像 DeepSpeed 和 Megatron-LM 这样的框架就能扩展 PyTorch 来实现这个功能哦。一个简单的张量并行实现示例如下:

import torch
import torch.distributed as distdef tensor_parallel_matmul(a, b, devices):# a 按行分割,b 在设备间共享a_shard = a.chunk(len(devices), dim=0)results = []for i, dev in enumerate(devices):a_device = a_shard[i].to(dev)b_device = b.to(dev)results.append(torch.matmul(a_device, b_device))# 把各个设备的结果拼接起来return torch.cat(results, dim=0)# 示例用法:
a = torch.randn(1000, 512)  # 假设这个张量太大,一个 GPU 装不下
b = torch.randn(512, 256)
devices = ['cuda:0', 'cuda:1']result = tensor_parallel_matmul(a, b, devices)
重点收获
  • 大模型 — 当模型太大,装不下单个 GPU 的内存时,这种方法特别有效哦。
  • 分割权重 — 不是在每个设备上复制整个模型,张量并行会把模型的参数切片呢。
  • 集体计算 — 前向和反向传播是在 GPU 之间集体完成的,需要精心协调,以确保张量的所有部分都被正确计算呢。
  • 自定义操作 — 往往要用到专门的 CUDA 内核或者第三方库,才能高效地实现张量并行哦。
优点和注意事项
  • 内存效率 — 通过分割大型张量,你就能训练那些超出单个设备内存的模型啦。它还能显著减少矩阵操作的延迟呢。
  • 复杂性 — 设备之间的协调增加了额外的复杂性哦。当扩展到超过两个 GPU 时,开发者必须仔细管理同步呢。由于手动分割可能导致的负载不平衡,以及为了避免 GPU 空闲太久而需要进行的设备间通信,是这些实现中常见的问题呢。
  • 框架增强 — 像 Megatron-LM 这样的工具已经为张量并行树立了标杆,而且很多这样的框架都能和 PyTorch 无缝集成呢。不过,集成并不总是那么顺利哦。

3. 上下文并行

上下文并行采用了一种不同的方法,它针对的是输入数据的上下文维度,尤其在基于序列的模型(比如 Transformer)中特别厉害呢。主要思想就是把长序列或者上下文信息分割开来,让不同的部分同时进行处理呢。这样能让模型在不超出内存或者计算能力的情况下,处理更长的上下文哦。当需要一起训练多个任务时,比如在多任务 NLP 模型中,这种方法就特别有用啦。

和张量并行类似,PyTorch 本身并没有原生支持上下文并行呢。不过,通过巧妙地重构数据,我们就能有效地管理长序列啦。想象一下,有一个 Transformer 模型需要处理长文本 —— 可以把序列分解成更小的片段,然后并行处理,最后再合并起来呢。

下面就是一个自定义 Transformer 块中上下文如何分割的示例哦。在这个示例中,这个块可能会并行处理长序列的不同片段,然后把输出合并起来进行最后的处理呢。

import torch
import torch.nn as nnclass ContextParallelTransformer(nn.Module):def __init__(self, d_model, nhead, context_size):super(ContextParallelTransformer, self).__init__()self.context_size = context_sizeself.transformer_layer = nn.TransformerEncoderLayer(d_model=d_model, nhead=nhead)def forward(self, x):# x 的形状:[batch, seq_len, d_model]batch, seq_len, d_model = x.size()assert seq_len % self.context_size == 0, \"序列长度必须能被 context_size 整除"# 把序列维度分割成片段segments = x.view(batch, seq_len // self.context_size,self.context_size, d_model)# 使用循环或者并行映射并行处理每个片段processed_segments = []for i in range(segments.size(1)):segment = segments[:, i, :, :]processed_segment = self.transformer_layer(segment.transpose(0, 1))processed_segments.append(processed_segment.transpose(0, 1))# 把处理过的片段拼接回完整的序列return torch.cat(processed_segments, dim=1)# 示例用法:
model = ContextParallelTransformer(d_model=512, nhead=8, context_size=16)
# [batch, sequence_length, embedding_dim]
input_seq = torch.randn(32, 128, 512)
output = model(input_seq)
重点收获
  • 序列分割 — 把序列或者上下文维度分割开来,就能在不同的数据片段上并行计算啦。
  • 长序列的可扩展性 — 这对于处理特别长的序列的模型特别有用,要是把整个上下文一次性处理,那既不可能,也不高效哦。
  • 注意力机制 — 在 Transformer 中,把注意力计算分割到不同的片段上,能让每个 GPU 处理序列的一部分以及它相关的自注意力计算呢。
优点和注意事项
  • 高效的长序列处理 — 把长上下文分割成并行的片段,模型就能在不过度占用内存资源的情况下处理超长的序列啦。
  • 序列依赖性 — 必须特别注意跨越上下文片段边界的依赖关系哦。可能需要采用重叠片段或者额外的聚合步骤等技术呢。
  • 新兴领域 — 随着研究的不断深入,我们期待会有更多专门促进 PyTorch 中上下文并行的标准工具和库出现呢。

4. 流水线并行

None

流水线并行示意图 [图片来源]

流水线并行引入了把神经网络分割成一系列阶段的概念,每个阶段都在不同的 GPU 上进行处理呢。当数据流经网络时,中间结果会从一个阶段传递到下一个阶段,就像流水线一样呢。这种错开的执行方式能让计算和通信重叠起来,从而提高整体的吞吐量呢。

幸运的是,PyTorch 有一个现成的 API 支持这个功能,叫做 Pipe,用它就能非常轻松地创建分段的模型呢。这个 API 会自动把一个顺序模型分割成微批次,这些微批次会在指定的 GPU 上流动呢。

一个简单的使用示例如下:

import torch.nn as nn
from torch.distributed.pipeline.sync import Pipe# 定义模型的两个顺序片段
segment1 = nn.Sequential(nn.Linear(1024, 2048),nn.ReLU(),nn.Linear(2048, 2048)
)segment2 = nn.Sequential(nn.Linear(2048, 2048),nn.ReLU(),nn.Linear(2048, 1024)
)# 使用 Pipe 把片段组合起来
# 如果提供了设备分配,Pipe 会自动处理模块在设备上的放置
# 这里是自动分配的
model = nn.Sequential(segment1, segment2)
model = Pipe(model, chunks=4)# 现在,当你把数据传递给模型时,微批次就会以流水线的方式进行处理啦。
inputs = torch.randn(16, 1024)
outputs = model(inputs)import torch
import torch.nn as nn
from torch.distributed.pipeline.sync import Pipe# 定义模型片段
segment1 = nn.Sequential(nn.Linear(1024, 2048),nn.ReLU(),nn.Linear(2048, 2048)
)
segment2 = nn.Sequential(nn.Linear(2048, 2048),nn.ReLU(),nn.Linear(2048, 1024)
)# 使用 Pipe 把片段组合成一个模型
model = nn.Sequential(segment1, segment2)
# 把模型分割成微批次,这些微批次会在 'cuda:0''cuda:1' 设备上流动
model = Pipe(model, devices=['cuda:0', 'cuda:1'], chunks=4)# 模拟输入批次
inputs = torch.randn(16, 1024).to('cuda:0')
outputs = model(inputs)
重点收获
  • 分阶段计算 — 把模型分割成一系列阶段(或者叫“流水线”)。每个阶段都分配给不同的 GPU 哦。
  • 微批次 — 不是把一个大批次一次性传给一个阶段,而是把批次分割成微批次,这些微批次会持续不断地流经流水线呢。
  • 提高吞吐量 — 通过确保所有设备都在同时工作(即使是在处理不同的微批次),流水线并行可以显著提高吞吐量哦。
优点和注意事项
  • 资源利用 — 流水线并行可以通过重叠不同阶段的计算,提高 GPU 的利用率哦。
  • 延迟与吞吐量的权衡 — 虽然吞吐量提高了,但可能会因为引入的流水线延迟,稍微影响一下延迟呢。
  • 复杂的调度 — 有效的微批次调度和负载平衡对于在各个阶段实现最佳性能至关重要哦。

5. 专家并行

None

专家并行 [图片来源]

专家并行是一种受 混合专家模型(MoE) 启发的技术,旨在在保持计算成本可控的同时,扩展模型的容量呢。在这个范式中,模型由多个专门的“专家”组成 —— 这些子网络通过一个门控机制,为每个输入选择性地激活呢。对于每个样本,只有部分专家会参与处理,这样就能在不大幅增加计算开销的情况下,拥有巨大的模型容量啦。

None

混合专家模型使用的门控函数 [图片来源]

同样呢,PyTorch 并没有直接提供现成的专家并行解决方案哦,不过它模块化的设计使得创建自定义实现成为可能呢。这种策略通常涉及定义一组专家层,以及一个决定激活哪些专家的门控器呢。

在生产环境中,专家并行通常会和其他并行策略结合起来使用哦。比如,你可以同时使用数据并行和专家并行,既能处理大型数据集,又能处理大量的模型参数 —— 同时,还能通过门控机制,把计算有选择性地路由到合适的专家那里呢。下面就是一个简化版的实现示例:

import torch
import torch.nn as nn
import torch.nn.functional as Fclass Expert(nn.Module):def __init__(self, input_dim, output_dim):super(Expert, self).__init__()self.fc = nn.Linear(input_dim, output_dim)def forward(self, x):return F.relu(self.fc(x))class MoE(nn.Module):def __init__(self, input_dim, output_dim, num_experts, k=2):super(MoE, self).__init__()self.num_experts = num_expertsself.k = k  # 每个样本使用的专家数量self.experts = nn.ModuleList([Expert(input_dim, output_dim)for _ in range(num_experts)])self.gate = nn.Linear(input_dim, num_experts)def forward(self, x):# x 的形状:[batch, input_dim]gate_scores = self.gate(x)  # [batch, num_experts]# 为每个输入选择 top-k 个专家topk = torch.topk(gate_scores, self.k, dim=1)[1]outputs = []for i in range(x.size(0)):expert_output = 0for idx in topk[i]:expert_output += self.experts[idx](x[i])outputs.append(expert_output / self.k)return torch.stack(outputs)# 示例用法:
batch_size = 32
input_dim = 512
output_dim = 512
num_experts = 4
model = MoE(input_dim, output_dim, num_experts)
x = torch.randn(batch_size, input_dim)
output = model(x)
重点收获
  • 混合专家 — 对于每个训练样本,只使用部分专家,这样就能在不大幅增加每个样本计算量的情况下,保持巨大的模型容量哦。
  • 动态路由 — 门控函数会动态决定哪些专家应该处理每个输入标记或者数据片段呢。
  • 专家级别的并行 — 专家可以在多个设备上分布开来,这样就能并行计算,进一步减少瓶颈啦。
优点和注意事项
  • 可扩展的模型容量 — 专家并行让你能够构建出容量巨大的模型,而不会因为每个输入都增加计算量哦。
  • 高效的计算 — 通过只为每个输入处理选定的专家子集,就能实现高效的计算啦。
  • 路由复杂性 — 门控机制非常关键哦。要是设计得不好,可能会导致负载不平衡和训练不稳定呢。
  • 研究前沿 — 专家并行仍然是一个活跃的研究领域,目前正在进行的研究旨在改进门控方法以及专家之间的同步呢。

6. ZeRO:零冗余优化器

None

分区策略和 GPU 性能 [图片来源]

ZeRO,也就是 零冗余优化器,在大规模训练的内存优化方面可是个突破性的成果哦。作为 DeepSpeed 库的一部分,ZeRO 通过分区优化器状态、梯度和模型参数,解决了分布式训练中的内存限制问题呢。说白了,ZeRO 就是消除了每个 GPU 都保存一份所有东西的冗余,从而节省了大量的内存呢。

它的运作方式是把优化器状态和梯度的存储分散到所有参与的设备上,而不是复制它们呢。这种策略不仅能减少内存使用量,还能让那些原本会超出单个 GPU 内存容量的模型也能进行训练呢。ZeRO 通常会分三个阶段来实现,每个阶段都针对不同的内存冗余问题:

ZeRO-1:优化器状态分区
  • 把优化器状态(比如动量缓冲区)分区到各个 GPU 上呢
  • 每个 GPU 只保存其参数部分的优化器状态哦
  • 模型参数和梯度仍然在所有 GPU 上复制呢
ZeRO-2:梯度分区
  • 包含了 ZeRO-1 的所有内容呢
  • 另外还会把梯度分区到各个 GPU 上哦
  • 每个 GPU 只计算并保存其参数部分的梯度呢
  • 模型参数仍然在所有 GPU 上复制呢
ZeRO-3:参数分区
  • 包含了 ZeRO-1 和 ZeRO-2 的所有内容呢
  • 另外还会把模型参数分区到各个 GPU 上哦
  • 每个 GPU 只保存模型参数的一部分呢
  • 在前向和反向传播过程中需要收集参数呢
    在这里插入图片描述

ZeRO Offload 的架构 [图片来源]

ZeRO 提供了最大的灵活性,因为它结合了数据和模型并行的好处,如上图所示呢。

虽然 ZeRO 是 DeepSpeed 的一个特性,但它和 PyTorch 的集成使得它成为了训练优化工具箱中的一个重要工具,有助于高效地管理内存,并让以前无法训练的模型大小在现代硬件上成为可能呢。下面是一个示例实现:

import torch
import torch.nn as nn
import deepspeedclass LargeModel(nn.Module):def __init__(self, input_dim, hidden_dim, output_dim):super(LargeModel, self).__init__()self.fc1 = nn.Linear(input_dim, hidden_dim)self.relu = nn.ReLU()self.fc2 = nn.Linear(hidden_dim, output_dim)def forward(self, x):x = self.relu(self.fc1(x))return self.fc2(x)model = LargeModel(1024, 4096, 10)# DeepSpeed 配置,带有 ZeRO 优化器设置
ds_config = {"train_batch_size": 32,"optimizer": {"type": "Adam","params": {"lr": 0.001}},"zero_optimization": {"stage": 2,  # 第 2 阶段:梯度分区"allgather_partitions": True,"reduce_scatter": True,"allgather_bucket_size": 2e8,"overlap_comm": True}
}# 用 ZeRO 初始化 DeepSpeed 和模型
model_engine, optimizer, _, _ = deepspeed.initialize(model=model,config=ds_config)
inputs = torch.randn(32, 1024).to(model_engine.local_rank)
outputs = model_engine(inputs)
loss = outputs.mean()  # 简化的损失计算
model_engine.backward(loss)
model_engine.step()
重点收获
  • 阶段选择 — ZeRO 通常分多个阶段实现,每个阶段在内存节省和通信开销之间提供了不同的平衡呢。根据模型大小、网络能力以及可以接受的通信开销水平,选择合适的阶段至关重要哦。
  • 与其他技术的集成 — 它可以无缝地融入一个可能还包括上述并行策略的生态系统中呢。
优点和注意事项
  • 通信开销 — 这种策略的一个固有挑战是,减少内存冗余通常会增加 GPU 之间的数据交换量哦。因此,高效利用高速互连(比如 NVLink 或 InfiniBand)就变得更加关键啦,因为这个原因。
  • 配置复杂性 — ZeRO 比传统优化器引入了更多的配置参数呢。这些设置需要仔细地进行实验和分析,以匹配硬件的优势,确保优化器能够高效运行呢。设置内容包括但不限于 — 适当的梯度聚合桶大小,以及各种状态(优化器状态、梯度、参数)的分区策略。
  • 强大的监控 — 在启用 ZeRO 的训练中调试问题可能会非常困难哦。因此,提供对 GPU 内存使用情况、网络延迟以及整体吞吐量等信息的监控工具就变得至关重要啦,因为这个原因。

把它们全部结合起来

None

并行的各种混合方法 [图片来源]

在超大规模下训练深度学习模型,很多时候都需要采用混合方法 —— 通常会结合上述提到的这些技术呢。比如,一个最先进的 LLM 可能会使用数据并行来在节点之间分配批次,张量并行来分割巨大的权重矩阵,上下文并行来处理长序列,流水线并行来连接顺序模型阶段,专家并行来动态分配计算资源,最后再用 ZeRO 来优化内存使用呢。这种协同作用确保了即使是参数数量天文数字级别的模型,也仍然能够进行训练,并且保持高效的哦。

搞清楚在什么时候、在什么地方以及如何使用这些技术,对于突破可能的极限至关重要呢。再加上 PyTorch 的模块化和即插即用的库,构建能够突破传统硬件限制的健壮、可扩展的训练管道,已经变得越来越容易被更多人掌握了呢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/906379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

提示工程(Prompt Engineering)应用技巧

Prompt(提示)就是用户与大模型交互输入的代称。即我们给大模型的输入称为 Prompt,而大模型返回的输出一般称为 Completion。 Prompt 需要清晰明确地表达需求,提供充足上下文,使语言模型能够准确理解我们的意图。更长、…

[原创](现代Delphi 12指南):[macOS 64bit App开发]: 如何获取目录大小?

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

Unity入门学习(四)3D数学(4)之四元数Quaternion

目录 一、什么是四元数 二、和欧拉角的关联以及为什么会出现四元数 三、四元数的基本组成 Unity中的表示: 四、四元数Quaternion这个类中具有的属性和方法 常用属性 核心方法 五、四元数之间的计算 1. 叉乘(组合旋转) 2. 点积&#…

活体检测接口全面评测:2025年活体检测选择指南

一、活体检测:数字化时代的身份验证基石 活体检测是一种通过分析人体生物特征动态变化来验证身份真实性的技术,其核心在于区分真实人体与伪造样本(如照片、视频、3D 面具等)。技术原理主要基于以下维度: 多模态数据采…

物联网工程毕业设计课题实践指南

1. 智能家居控制系统 1.1 基于ZigBee的智能家居控制 实践过程 硬件选型主控:CC2530/CC2531传感器:温湿度、光照、人体红外执行器:继电器、电机、LED灯系统架构 A[传感器层] --> B[ZigBee网络] B --> C[网关] C --> D[云平台] D --> E[手机APP] 开…

电网中窃电分析:概念、算法与应用

一、引言 在现代电力系统中,窃电行为是一个严重影响电网经济运行和供电秩序的问题。窃电不仅导致供电企业的经济损失,破坏了电力市场的公平性,还可能对电网的安全稳定运行构成威胁,甚至引发安全事故。随着科技的不断进步&#xff…

一洽小程序接入说明

接入说明 文档以微信小程序作为示例介绍,其他小程序接入操作与此类似 1、添加校验文件 开发者使用微信小程序提供的 webview 组件可以实现打开一洽的H5对话 小程序的“域名配置”中添加一洽的对话域名地址,需要获取校验文件提供给一洽放在域名根目录下…

【数据结构 -- AVL树】用golang实现AVL树

目录 引言定义旋转方式LL型RR型LR型RL型 实现结构获取结点高度平衡因子更新高度左旋右旋插入结点中序遍历 引言 AVL树,基于二叉搜索树通过平衡得到 前面我们知道,通过🔗二叉搜索树可以便捷快速地查找到数据,但是当序列有序时&am…

PyTorch图像识别模型和图像分割模型体验

文章目录 仓库地址练习:图像自动识别模型数据集说明模型训练和保存导入数据集搭建神经网络训练和保存实现 模型测试测试代码测试结果 练习:图像自动分割模型模型训练和保存加载数据集搭建神经网络训练和保存 模型测试测试代码测试效果 仓库地址 图像识别…

威纶通触摸屏IP地址设定步骤及程序下载指南

在使用威纶通触摸屏时,正确设定IP地址以及完成程序下载是确保其正常运行和实现功能的关键步骤。本文将详细介绍威纶通触摸屏IP地址设定步骤及程序下载的方法。 一、IP地址设定步骤 (一)前期准备 确保威纶通触摸屏已经通电并启动&#xff0…

一文读懂|大模型智能体互操作协议:MCP/ACP/A2A/ANP

导读 随着推理大模型的出现(deepseek,Qwen3等),进一步地推进了大模型的智能体系统发展。然而,如何使智能体更好的调用外部工具,智能体与智能体之间如何有机地协作,仍然没有一个完美的答案。这篇…

前端下载ZIP包方法总结

在前端实现下载 ZIP 包到本地,通常有以下几种方法,具体取决于 ZIP 包的来源(静态文件、后端生成、前端动态生成等): 方法 1:直接下载静态文件(最简单) 如果 ZIP 包是服务器上的静态…

简单使用Slidev和PPTist

简单使用Slidev和PPTist 1 简介 前端PPT制作有很多优秀的工具包,例如:Slidev、revealjs、PPTist等,Slidev对Markdown格式支持较好,适合与大模型结合使用,选哟二次封装;revealjs适合做数据切换&#xff0c…

数据挖掘:从数据堆里“淘金”,你的数据价值被挖掘了吗?

数据挖掘:从数据堆里“淘金”,你的数据价值被挖掘了吗? 在这个数据爆炸的时代,我们每天都在产生海量信息:社交媒体上的点赞、网购时的浏览记录,甚至是健身手环记录下的步数。这些数据本身可能看似杂乱无章…

程序运行报错分析文档

zryhuawei:~/src/modules/Connect$ ./newbuild/OpConnectAidTool \WARNING: MYSQL_OPT_RECONNECT is deprecated and will be removed in a future version. replace into process_tracking (step_id,date,status,context_data,start_time,end_time,error_log) values(?,?,?…

基于flask+vue的电影可视化与智能推荐系统

基于flaskvue爬虫的电影数据的智能推荐与可视化系统,能展示电影评分、评论情感分析等直观的数据可视化图表,还能通过协同过滤算法为用户提供个性化电影推荐,帮助用户发现更多感兴趣的电影作品,具体界面如图所示。 本系统主要技术架…

BYUCTF 2025

几周没会的比赛了,都是一题游。这周的BYU还不错,难度适中,只是时间有点短。周末时间不够。 Crypto Many Primes from Crypto.Util.number import bytes_to_long, getPrime import randomflag open("flag.txt").read().encode()…

链表的面试题8之环形链表

许久不见,那么这是最后倒数第三题了,这道题我们来看一下环形链表。 老规矩贴链接:141. 环形链表 - 力扣(LeetCode) 目录 倒数第k个元素 获取中间元素的问题。 双指针 来,大致看一下题目,这…

在 JavaScript 中正确使用 Elasticsearch,第二部分

作者:来自 Elastic Jeffrey Rengifo 回顾生产环境中的最佳实践,并讲解如何在无服务器环境中运行 Elasticsearch Node.js 客户端。 想获得 Elastic 认证?查看下一期 Elasticsearch Engineer 培训的时间! Elasticsearch 拥有大量新…

2025年网站安全防御全解析:应对DDoS与CC攻击的智能策略

2025年,随着AI技术与物联网设备的深度融合,DDoS与CC攻击的规模与复杂度持续升级。攻击者不仅利用T级流量洪泛冲击带宽,还通过生成式AI伪造用户行为,绕过传统防御规则。如何在保障业务高可用的同时抵御混合型攻击?本文将…