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

PyTorch 多 GPU 入门:深入解析 nn.DataParallel 的工作原理与局限

当你发现单个 GPU 已经无法满足你训练庞大模型或处理海量数据的需求时,利用多 GPU 进行并行训练就成了自然的选择。PyTorch 提供了几种实现方式,其中 torch.nn.DataParallel (简称 DP) 因其使用的便捷性,常常是初学者接触多 GPU 训练的第一站。只需一行代码,似乎就能让你的模型在多张卡上跑起来!

但是,这种便捷性的背后隐藏着怎样的工作机制?它有哪些不为人知的性能瓶颈和局限性?为什么在更严肃的分布式训练场景下,大家通常更推荐 DistributedDataParallel (DDP)?

这篇博客将带你深入 nn.DataParallel 的内部,详细拆解它的执行流程,理解其优缺点,并帮助你判断它是否适合你的应用场景。

一、 nn.DataParallel 的核心思想:简单分工,集中汇报

想象一下,你是一位项目经理(主 GPU),手下有多位员工(其他 GPU)。现在有一个大任务(一个大的数据批次 Batch),你需要让大家协同完成。DP 的思路大致如下:

  1. 任务分发 (Scatter): 经理将大任务拆分成多个小任务(将 Batch 沿 batch 维度切分),分发给包括自己在内的每个员工(每个 GPU 分到一部分数据)。
  2. 工具复制 (Replicate): 经理把自己手头的完整工具箱(模型)复制一份给每个员工(每个 GPU 上都有一份完整的模型副本)。
  3. 并行处理 (Parallel Apply): 每个员工使用自己的工具(模型副本)处理分配到的小任务(数据子集),独立完成计算(前向传播)。
  4. 结果汇总 (Gather): 所有员工将各自的处理结果汇报给经理(将各个 GPU 的输出收集回主 GPU)。
  5. 最终评估 (Loss Calculation): 经理根据汇总的结果计算最终的评估指标(在主 GPU 上计算损失 Loss)。
  6. 反馈收集与整合 (Backward Pass & Gradient Summation): 当需要改进工作方法时(反向传播计算梯度),经理根据最终评估结果,让每个员工计算各自需要调整的方向(每个 GPU 计算本地梯度)。然后,所有员工将自己的反馈(梯度)全部发送给经理,经理将这些反馈累加起来,得到一个总的调整方向。
  7. 更新计划 (Optimizer Step): 经理根据这个整合后的总调整方向,更新自己手头的主计划书(只更新主 GPU 上的模型参数)。
  8. 下一轮开始: 经理再次复制最新的计划书给所有员工,开始新一轮的任务。

这个比喻虽然不完全精确,但抓住了 DP 的几个关键特点:模型复制、数据分发、并行计算、结果/梯度向主 GPU 汇总、只在主 GPU 更新模型。

二、 深入 nn.DataParallel 的内部机制 (Step-by-Step)

让我们更技术性地拆解一个典型的训练迭代中,nn.DataParallel 的具体工作流程:

前提:

  • 你有一个 PyTorch 模型 model
  • 你有多个可用的 GPU,例如 device_ids = [0, 1, 2, 3]
  • 你将模型包装起来:dp_model = nn.DataParallel(model, device_ids=device_ids)
  • 通常,device_ids[0] (也就是 GPU 0) 会成为主 GPU (Master GPU)输出设备 (Output Device),负责数据的分发、结果的收集和最终的损失计算。

一个训练迭代的流程:

  1. 数据准备: 你准备好一个批次的数据 inputs 和对应的标签 targets注意: 在将数据喂给 dp_model 之前,通常需要将它们手动移动到主 GPU (即 device_ids[0]) 上。这是一个常见的易错点。

    inputs = inputs.to(device_ids[0]) 
    targets = targets.to(device_ids[0])
    
  2. 前向传播 (outputs = dp_model(inputs)): 当你调用 dp_model 进行前向计算时,内部会发生以下步骤:

    • a) 数据分发 (Scatter): nn.DataParallel 调用类似 torch.nn.parallel.scatter 的函数。它将位于主 GPU 上的 inputs(通常是一个 Tensor 或包含 Tensor 的元组/字典)沿着批次维度 (dimension 0) 进行切分,分成 len(device_ids) 份。然后,它将每一份数据分别发送(拷贝)到 device_ids 列表中的对应 GPU 上。例如,如果 Batch Size 是 32,有 4 个 GPU,那么每个 GPU 会收到一个大小为 8 的子批次数据。
    • b) 模型复制 (Replicate): nn.DataParallel 调用类似 torch.nn.parallel.replicate 的函数。它将位于主 GPU 上的原始模型 model 的当前状态(包括参数和缓冲区)复制到列表 device_ids 中指定的每一个 GPU 上(包括主 GPU 自身)。这样每个 GPU 都有了一个独立的模型副本。这个复制操作在每次前向传播时都会发生,以确保所有副本都是最新的。
    • c) 并行计算 (Parallel Apply): nn.DataParallel 调用类似 torch.nn.parallel.parallel_apply 的函数。它在每个 GPU 上,使用该 GPU 上的模型副本和分配到的数据子集,并行地执行模型的前向传播计算。PyTorch 底层会利用 CUDA Stream 等机制来实现这种并行性。
    • d) 结果收集 (Gather): nn.DataParallel 调用类似 torch.nn.parallel.gather 的函数。它将每个 GPU 上的计算结果(模型的输出)收集(拷贝)回主 GPU,并将它们沿着批次维度 (dimension 0) 拼接起来,形成一个完整的、对应原始输入批次的输出 outputs。这个 outputs 张量最终位于主 GPU 上。
  3. 损失计算 (loss = criterion(outputs, targets)): 损失函数 criterion主 GPU 上执行,使用从所有 GPU 收集回来的 outputs 和同样位于主 GPU 上的 targets 来计算总的损失值 loss

  4. 反向传播 (loss.backward()): 这是最关键也最容易误解的部分:

    • 当你对主 GPU 上的 loss 调用 .backward() 时,PyTorch 的 Autograd 引擎开始工作,从 loss 开始沿着计算图反向传播。
    • 这个计算图是连接起来的!它知道 loss 是由主 GPU 上的 outputs 计算得来的,而 outputs 是通过 gather 操作从各个 GPU 上的副本模型的输出收集来的。Autograd 会将梯度信号反向传播通过 gather 操作
    • 然后,梯度信号会进一步反向传播到每个 GPU 上的 parallel_apply 步骤,也就是每个模型副本的前向计算过程。
    • 因此,每个模型副本都会计算出其参数相对于最终 loss 的梯度。重要的是: 每个副本计算梯度时,使用的是它在前向传播中接收到的那部分数据子集
    • 梯度汇总: 在计算完每个副本的梯度后,nn.DataParallel 的魔法来了:它会自动地将所有副本 GPU 上的梯度拷贝主 GPU,并在主 GPU 上将它们逐元素相加 (Summation)。最终,主 GPU 上原始模型 model.grad 属性存储的是所有 GPU 梯度的总和
  5. 优化器更新 (optimizer.step()):

    • 优化器 optimizer (它通常是围绕原始模型 model 的参数创建的)读取主 GPU 上 model 参数的 .grad 属性(也就是所有梯度的总和)。
    • 优化器根据这个总梯度和学习率等策略,只更新主 GPU 上的原始模型 model 的参数
    • 注意: 副本 GPU 上的模型参数不会被优化器直接更新。它们会在下一次迭代的前向传播开始时,通过 replicate 步骤从主 GPU 上的 model 重新复制过去,从而获得更新。

三、 图解流程 (简化版)

graph TDsubgraph 主 GPU (GPU 0)A[Input Batch (on GPU 0)] --> B{Scatter};B -->|Sub-batch 0| C0[Model Replica (GPU 0)];H0[Replica Output 0] --> I{Gather};I --> J[Final Output (on GPU 0)];J --> K[Loss Calculation];K -- loss.backward() --> L{Gradient Summation};M[Optimizer Step] --> N(Updated Model Parameters on GPU 0);endsubgraph 副本 GPU 1B -->|Sub-batch 1| C1[Model Replica (GPU 1)];C1 -->|Forward Pass| H1[Replica Output 1];H1 --> I;K -- Autograd --> G1(Gradient Calculation on GPU 1);G1 -->|Copy Gradient| L;endsubgraph 副本 GPU 2B -->|Sub-batch 2| C2[Model Replica (GPU 2)];C2 -->|Forward Pass| H2[Replica Output 2];H2 --> I;K -- Autograd --> G2(Gradient Calculation on GPU 2);G2 -->|Copy Gradient| L;endsubgraph 副本 GPU 3B -->|Sub-batch 3| C3[Model Replica (GPU 3)];C3 -->|Forward Pass| H3[Replica Output 3];H3 --> I;K -- Autograd --> G3(Gradient Calculation on GPU 3);G3 -->|Copy Gradient| L;endN -.->|Next Iteration: Replicate| C0;N -.->|Next Iteration: Replicate| C1;N -.->|Next Iteration: Replicate| C2;N -.->|Next Iteration: Replicate| C3;style M fill:#f9f,stroke:#333,stroke-width:2pxstyle L fill:#ccf,stroke:#333,stroke-width:2pxstyle I fill:#ccf,stroke:#333,stroke-width:2pxstyle B fill:#ccf,stroke:#333,stroke-width:2px
  • 蓝色节点 (Scatter, Gather, Gradient Summation) 代表数据在 GPU 间流动的关键聚合/分散点,通常发生在主 GPU 上或以主 GPU 为中心。
  • 粉色节点 (Optimizer Step) 代表只在主 GPU 上发生的操作。

四、 nn.DataParallel 的优点

  • 简单易用: 只需要将模型用 nn.DataParallel 包装一下,对现有单 GPU 代码的改动非常小。
  • 单进程: 所有 GPU 都在同一个 Python 进程中运行,共享相同的进程空间,调试相对直观(虽然 GIL 会限制 CPU 并行性)。

五、 nn.DataParallel 的显著缺点 (为什么通常不推荐)

尽管简单,DP 却存在几个严重的性能和效率问题:

  1. 主 GPU 负载不均 (严重瓶颈):

    • 数据分发 (Scatter): 需要从主 GPU 发送数据到所有其他 GPU。
    • 结果收集 (Gather): 所有 GPU 的输出都需要拷贝回主 GPU。
    • 损失计算: 只在主 GPU 进行。
    • 梯度汇总 (Summation): 所有 GPU 的梯度都需要拷贝回主 GPU 并相加。
    • 参数更新: 只在主 GPU 进行。
    • 结果: 主 GPU (通常是 GPU 0) 的计算负载、显存占用和通信开销远大于其他 GPU,导致它成为性能瓶颈,其他 GPU 经常处于等待状态,整体加速比(使用 N 个 GPU 相对于 1 个 GPU 的速度提升)远低于 N。
  2. 全局解释器锁 (GIL) 限制: 由于所有 GPU 都在一个 Python 进程中运行,Python 的 GIL 会阻止真正的 CPU 级并行。虽然 GPU 计算是并行的,但驱动 GPU 的 Python 代码(数据加载、预处理、控制流等)可能会受到 GIL 的限制,尤其是在数据加载或 CPU 密集型操作成为瓶颈时。

  3. 网络效率低下 (相对 DDP): DP 的 Scatter/Gather 通信模式不如 DDP 使用的 AllReduce 高效。AllReduce 可以通过 Ring 或 Tree 等算法优化通信路径,避免所有数据都汇集到单一节点。

  4. 显存使用不均衡: 主 GPU 需要存储原始模型、所有副本的输出、所有副本的梯度总和,以及优化器状态等,其显存占用通常比其他 GPU 高得多。这限制了模型的大小或批次大小(由主 GPU 的显存决定)。

  5. 不支持模型并行: DP 主要用于数据并行,很难与其他并行策略(如模型并行)结合。

六、 何时可以考虑使用 nn.DataParallel

  • 快速原型验证: 当你想快速将单 GPU 代码扩展到少量 GPU (例如 2-4 个) 上,验证想法,且对极致性能要求不高时。
  • 教学或简单示例: 用于演示多 GPU 的基本概念。
  • 负载非常小的模型: 如果模型非常小,计算量远大于通信开销,DP 的瓶颈可能不那么明显。

七、 总结与建议

nn.DataParallel 以其简洁的 API 提供了一种快速上手多 GPU 训练的方式。它通过复制模型、分发数据、并行计算、聚合结果/梯度到主 GPU、在主 GPU 上更新模型的流程工作。

然而,其主 GPU 瓶颈、GIL 限制、通信效率低下和显存不均衡等问题,使得它在大多数严肃的训练任务中性能不佳,加速比较低。

因此,对于追求高性能、高效率、可扩展性的多 GPU 或分布式训练,强烈推荐使用 torch.nn.parallel.DistributedDataParallel (DDP)。DDP 采用多进程架构,避免了 GIL 问题,使用高效的 AllReduce 操作进行梯度同步,负载更均衡,性能通常远超 DP。虽然 DDP 的设置比 DP 稍微复杂一些(需要初始化进程组、使用 DistributedSampler 等),但带来的性能提升和更好的可扩展性通常是值得的。

理解 DP 的工作原理有助于我们更好地认识到它的局限性,并更有动力去学习和掌握更先进的 DDP 技术。

相关文章:

PyTorch 多 GPU 入门:深入解析 nn.DataParallel 的工作原理与局限

当你发现单个 GPU 已经无法满足你训练庞大模型或处理海量数据的需求时,利用多 GPU 进行并行训练就成了自然的选择。PyTorch 提供了几种实现方式,其中 torch.nn.DataParallel (简称 DP) 因其使用的便捷性,常常是初学者接触多 GPU 训练的第一站…...

UDP协议理解

文章目录 UDP协议理解UDP 协议的特点:UDP协议图示UDP 的头部结构:UDP数据传输图示 UDP 的应用场景:TCP 与UDP对比UDP的传输丢包和顺序错乱问题(了解)丢包的解决方法:顺序错乱的解决方法:综合应用…...

微信小程序拖拽排序有效果图

效果图 .wxml <view class"container" style"--w:{{w}}px;" wx:if"{{location.length}}"><view class"container-item" wx:for"{{list}}" wx:key"index" data-index"{{index}}"style"--…...

算力网络的早期有关论文——自用笔记

2023年底至2024年初阅读有关论文的自用笔记&#xff0c;作为参考。 算力网络架构 https://baijiahao.baidu.com/s?id1727377583404975414&wfrspider&forpc think&note 是否可以和cpu进程调度联系。 目前&#xff1a;看一些综述深一步了解背景和发展现状,完善认…...

卷积神经网络基础(四)

今天我们继续学习各个激活函数层的实现过程。 目录 5.2 Sigmoid层 六、Affine/Softmax层实现 6.1 Affine层 6.2 批处理版本 5.2 Sigmoid层 sigmoid函数的表达式如下&#xff1a; 用计算图表示的话如下&#xff1a; 计算过程稍微有些复杂&#xff0c;且这里除了乘法和加法…...

【MySQL数据库】表的约束

目录 1&#xff0c;空属性 2&#xff0c;默认值 3&#xff0c;列描述 4&#xff0c;zerofill 5&#xff0c;主键primary key 6&#xff0c;自增长auto_increment 7&#xff0c;唯一键unique 8&#xff0c;外键foreign key 在MySQL中&#xff0c;表的约束是指用于插入的…...

网络威胁情报 | Friday Overtime Trooper

本文将分别从两个环境出发&#xff0c;以实践来体验利用威胁情报分析可疑文件的过程。 Friday Overtime 现在你是一位安全分析人员&#xff0c;正在美美等待周五过去&#xff0c;但就在即将下班之时意外发生了&#xff1a;你的客户发来求助&#xff0c;说他们发现了一些可疑文…...

GPIO(通用输入输出端口)详细介绍

一、基本概念 GPIO&#xff08;General - Purpose Input/Output&#xff09;即通用输入输出端口&#xff0c;是微控制器&#xff08;如 STM32 系列&#xff09;中非常重要的一个外设。它是一种软件可编程的引脚&#xff0c;用户能够通过编程来控制这些引脚的输入或输出状态。在…...

学习笔记——《Java面向对象程序设计》-继承

参考教材&#xff1a; Java面向对象程序设计&#xff08;第3版&#xff09;微课视频版 清华大学出版社 1、定义子类 class 子类名 extends 父类名{...... }如&#xff1a; class Student extends People{...... } &#xff08;1&#xff09;如果一个类的声明中没有extends关…...

基于javaweb的SpringBoot校园失物招领系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

什么事Nginx,及使用Nginx部署vue项目(非服务器Nginx压缩包版)

什么是 Nginx? Nginx(发音为 “engine-x”)是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。它以其高性能、高并发处理能力和低资源消耗而闻名。以下是 Nginx 的主要特性和用途: 主要特性 高性能和高并发 Nginx 能够处理大量并发连接,适合高…...

nodejs使用require导入npm包,开发依赖和生产依赖 ,全局安装

nodejs使用require导入npm包&#xff0c;开发依赖和生产依赖 &#xff0c;全局安装 ✅ 一、Node.js 中使用 require() 导入 npm 包 // 导入第三方包&#xff08;例如 axios&#xff09; const axios require(axios);// 使用 axios.get(https://api.example.com).then(res &g…...

CSS在线格式化 - 加菲工具

CSS在线格式化 打开网站 加菲工具 选择“CSS在线格式化” 或者直接访问 https://www.orcc.top/tools/css 输入CSS代码&#xff0c;点击左上角的“格式化”按钮 得到格式化后的结果...

图片转base64 - 加菲工具 - 在线转换

图片转base64 - 加菲工具 先进入“加菲工具” 网 打开 https://www.orcc.top&#xff0c; 选择 “图片转base64”功能 选择需要转换的图片 复制 点击“复制”按钮&#xff0c;即可复制转换好的base64编码数据&#xff0c;可以直接用于img标签。...

性能比拼: Redis vs Dragonfly

本内容是对知名性能评测博主 Anton Putra Redis vs Dragonfly Performance (Latency - Throughput - Saturation) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本视频中&#xff0c;我们将对比 Redis 和 Dragonfly。我们将观察 set 与 get 操作的延迟&#xff…...

如何收集用户白屏/长时间无响应/接口超时问题

想象一下这样的场景:一位用户在午休时间打开某电商应用,准备购买一件心仪已久的商品。然而,页面加载了数秒后依然是一片空白,或者点击“加入购物车”按钮后没有任何反馈,甚至在结算时接口超时导致订单失败。用户的耐心被迅速消耗殆尽,关闭应用,转而选择了竞争对手的产品…...

来啦,烫,查询达梦表占用空间

想象一下oracle&#xff0c;可以查dba_segments&#xff0c;但是这个不可靠&#xff08;达梦官方连说明书都没有&#xff09; 先拼接一个sql set lineshow off SELECT SELECT ||||OWNER|||| AS OWNER,||||TABLE_NAME|||| AS TABLE_NAME,TABLE_USED_SPACE(||||OWNER||||,||||T…...

# 利用迁移学习优化食物分类模型:基于ResNet18的实践

利用迁移学习优化食物分类模型&#xff1a;基于ResNet18的实践 在深度学习的众多应用中&#xff0c;图像分类一直是一个热门且具有挑战性的领域。随着研究的深入&#xff0c;我们发现利用预训练模型进行迁移学习是一种非常有效的策略&#xff0c;可以显著提高模型的性能&#…...

AT24C02芯片简介:小巧强大的串行EEPROM存储器

一、AT24C02概述 AT24C02是一款2K位&#xff08;即256字节&#xff09;的串行EEPROM芯片&#xff0c;采用IC&#xff08;Inter-Integrated Circuit&#xff09;总线进行通信&#xff0c;适合低功耗、小容量存储需求。 主要特性&#xff1a; 项目 参数 存储容量 2Kb&#x…...

【Vue】状态管理(Vuex、Pinia)

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Vue 文章目录 1. 状态管理概述1.1 什么是状态管理1.2 为什么需要状态管理 2. Vuex基础2.1 Vuex核心概念2.1.1 State2.1.2 Getters2.1.3 Mutations2.1.4 Actions2.1.5 Modules 2.2 Vuex辅助函数2.2.1 mapState2.2.2 mapGetters2.…...

施磊老师基于muduo网络库的集群聊天服务器(四)

文章目录 实现登录业务登录业务代码补全数据库接口:查询,更新状态注意学习一下里面用到的数据库api测试与问题**问题1:****问题2:** 用户连接信息与线程安全聊天服务器是长连接服务器如何找到用户B的连接&#xff1f;在业务层存储用户的连接信息多线程安全问题加锁! 处理客户端…...

深度学习-全连接神经网络(过拟合,欠拟合。批量标准化)

七、过拟合与欠拟合 在训练深层神经网络时&#xff0c;由于模型参数较多&#xff0c;在数据量不足时很容易过拟合。而正则化技术主要就是用于防止过拟合&#xff0c;提升模型的泛化能力(对新数据表现良好)和鲁棒性&#xff08;对异常数据表现良好&#xff09;。 1. 概念认知 …...

访问Maven私服的教程

1.首先准备好maven私服的启动器&#xff0c;到bin目录下启动&#xff1a; 2.等待加载&#xff0c;加载过程比较长: 3.访问端口号: 4.仓库简介: 5.在maven的setting中 servers配置信息(设置私服访问的密码): 6.配置私服仓库地址: 7.配置上传地址(私服地址): 8.在自己的副项…...

Linux系统编程 day9 SIGCHLD and 线程

SIGCHLD信号 只要子进程信号发生改变&#xff0c;就会产生SIGCHLD信号。 借助SIGCHLD信号回收子进程 回收子进程只跟父进程有关。如果不使用循环回收多个子进程&#xff0c;会产生多个僵尸进程&#xff0c;原因是因为这个信号不会循环等待。 #include<stdio.h> #incl…...

Linux 内核中 cgroup 子系统 cpuset 是什么?

cpuset 是 Linux 内核中 cgroup&#xff08;控制组&#xff09; 的一个子系统&#xff0c;用于将一组进程&#xff08;或任务&#xff09;绑定到特定的 CPU 核心和 内存节点&#xff08;NUMA 节点&#xff09;上运行。它通过限制进程的 CPU 和内存资源的使用范围&#xff0c;优…...

乐视系列玩机---乐视2 x520 x528等系列线刷救砖以及刷写第三方twrp 卡刷第三方固件步骤解析

乐视2 x520 x528 x526等,搭载了高通骁龙652处理器,骁龙652的GPU性能甚至优于前一年的骁龙810,配备了3GB RAM和32GB ROM的存储空间, 通过博文了解💝💝💝 1💝💝💝-----详细解析乐视2 x520系列黑砖线刷救砖的步骤 2💝💝💝----官方两种更新卡刷步骤以及刷…...

电容加速电路!

大家好&#xff0c;我是记得诚。 今天分享一个小电路&#xff1a;电容加速电路。 下面是一个普通的三极管开关电路&#xff0c;区别是多了一个C1&#xff0c;C1被称为加速电容。作用是&#xff1a;加速三极管VT1的开通和截止&#xff0c;做到快开快关。 工作原理&#xff1a;…...

MCP Host、MCP Client、MCP Server全流程实战

目录 准备工作 MCP Server 实现 调试工作 MCP Client 实现 MCP Host 配置 第一步:配置支持 function calling的 LLM 第二步:添加MCP Server 一般有两种方式,第一种json配置,第二种直接是Command形式,我这里采用Command形式 第三步:使用MCP Server 准备工作 安装…...

Win10一体机(MES电脑设置上电自动开机)

找个键盘&#xff0c;带线的那种&#xff0c;插到电脑上&#xff0c;电脑开机&#xff1b;连续点按F11&#xff1b;通过↑↓键选择Enter Setup 然后回车&#xff1b; 选择 smart settings &#xff1b; 选择 Restore AC Power Loss By IO 回车&#xff1b; 将prower off 改为…...

强化学习和微调 区别如下

强化学习和微调 区别如下 定义与概念 强化学习**:是一种机器学习范式,强调智能体(agent)如何在环境中采取一系列行动,以最大化累积奖励**。智能体通过与环境进行交互,根据环境反馈的奖励信号来学习最优的行为策略。例如,机器人通过不断尝试不同的动作来学习如何在复杂环…...

【EasyPan】文件上传、文件秒传、文件转码、文件合并、异步转码、视频切割分析

【EasyPan】项目常见问题解答&#xff08;自用&持续更新中…&#xff09;汇总版 文件上传方法解析 一、方法总览 Transactional(rollbackFor Exception.class) public UploadResultDto uploadFile(...)核心能力&#xff1a; 秒传验证&#xff1a;通过MD5文件大小实现文…...

React18+ 项目搭建-从初始化、技术选型到开发部署的全流程规划

搭建一个 React 项目需要从项目初始化、技术选型到开发部署的全流程规划。以下是详细步骤和推荐的技术栈&#xff1a; 一、项目初始化 1. 选择脚手架工具 推荐工具&#xff1a; Vite&#xff08;现代轻量级工具&#xff0c;支持 React 模板&#xff0c;速度快&#xff09;&am…...

day3 打卡训练营

循环语句和判断语句之前已经会了&#xff0c;把列表的方法练一练 浙大疏锦行 python训练营介绍...

MySQL VS SQL Server:优缺点全解析

数据库选型、企业协作、技术生态、云数据库 1.1 MySQL优缺点分析 优点 开源免费 社区版完全免费&#xff0c;适合预算有限的企业 允许修改源码定制功能&#xff08;需遵守GPL协议&#xff09; 跨平台兼容性 支持Windows/Linux/macOS&#xff0c;适配混合环境部署 云服务商…...

【CPP】固定大小内存池

程序运行时&#xff0c;通常会频繁地进行内存的分配和释放操作。传统的内存分配方式&#xff08;如使用new和delete运算符&#xff09;可能会导致内存碎片的产生&#xff0c;并且每次分配和释放内存都有一定的时间开销。内存池通过在程序启动时一次性分配一大块内存或一次性分配…...

[数据结构]树和二叉树

概念 树是一种 非线性 的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09;个有限结点组成一个具有层次关系的集合。 树形结构中&#xff0c;子树之间不能有交集&#xff0c;否则就不是树形结构 双亲结点或父结点 &#xff1a;若一个结点含有子结点&#xff0c;则…...

监控页面卡顿PerformanceObserver

监控页面卡顿PerformanceObserver 性能观察器掘金 const observer new PerformanceObserver((list) > {}); observer.observe({entryTypes: [longtask], })...

Web开发-JavaEE应用JNDI注入RMI服务LDAP服务DNS服务高版本限制绕过

知识点&#xff1a; 1、安全开发-JavaEE-JNDI注入-LADP&RMI&DNS等 2、安全开发-JavaEE-JNDI注入-项目工具&手工原理等 演示案例-WEB开发-JavaEE-JNDI注入&LDAP&RMI服务&DNS服务&高版本限制绕过 JNDI全称为 Java Naming and DirectoryInterface&am…...

深度学习训练中的显存溢出问题分析与优化:以UNet图像去噪为例

最近在训练一个基于 Tiny-UNet 的图像去噪模型时&#xff0c;我遇到了经典但棘手的错误&#xff1a; RuntimeError: CUDA out of memory。本文记录了我如何从复现、分析&#xff0c;到逐步优化并成功解决该问题的全过程&#xff0c;希望对深度学习开发者有所借鉴。 训练数据&am…...

【Spring】单例模式的创建方式(Bean解析)

在Java中&#xff0c;单例模式&#xff08;Singleton Pattern&#xff09;确保一个类只有一个实例&#xff0c;并提供全局访问点。以下是实现单例的五种常见方式&#xff1a;懒汉式、饿汉式、双重检查锁、静态内部类和枚举&#xff0c;包括代码示例和优缺点分析。 1. 懒汉式&am…...

小小矩阵设计

在电气设计图中&#xff0c;矩阵设计的接线方法是通过结构化布局实现多灵活链接的技术&#xff0c;常用于信号切换、配电调压或更加复杂的控制场景。 今天聊一种在电气图纸中用到的一种简单矩阵接法&#xff0c;一眼就看明白&#xff0c;很大程度简化了程序控制点和继电器的使用…...

IOT项目——双轴追光系统

双轴太阳能追光系统 - ESP32实现 系统概述 这个系统使用&#xff1a; ESP32开发板2个舵机&#xff08;水平方向和垂直方向&#xff09;4个光敏电阻&#xff08;用于检测光照方向&#xff09;适当的电阻&#xff08;用于光敏电阻分压&#xff09; 接线示意图 --------------…...

深度学习基石:神经网络核心知识全解析(一)

神经网络核心知识全解析 一、神经网络概述 神经网络作为机器学习领域的关键算法&#xff0c;在现代生活中发挥着重要作用&#xff0c;广泛应用于图像识别、语音处理、智能推荐等诸多领域&#xff0c;深刻影响着人们的日常生活。它通过模拟人类大脑神经系统的结构和功能&#…...

什么是 金字塔缩放(Multi-scale Input)

金字塔缩放 什么是金字塔缩放(Multi-scale Input)什么场景下会用到金字塔缩放?图像识别目标跟踪图像压缩视频处理如何在计算机程序中实现金字塔缩放?准备数据缩小数据(构建金字塔的上层)存储数据使用数据(在程序中应用金字塔缩放)金字塔缩放的记忆卡片什么是金字塔缩放(M…...

从零开始配置 Zabbix 数据库监控:MySQL 实战指南

Zabbix作为一款开源的分布式监控工具&#xff0c;在监控MySQL数据库方面具有显著优势&#xff0c;能够为数据库的稳定运行、性能优化和故障排查提供全面支持。以下是使用Zabbix监控MySQL数据库的配置。 一、安装 Zabbix Agent 和 MySQL 1. 安装 Zabbix Agent services:zabbix…...

机器学习超参数优化全解析

机器学习超参数优化全解析 摘要 本文全面深入地剖析了机器学习模型中的超参数优化策略&#xff0c;涵盖了从参数与超参数的本质区别&#xff0c;到核心超参数&#xff08;如学习率、批量大小、训练周期&#xff09;的动态调整方法&#xff1b;从自动化超参数优化技术&#xf…...

【算法】双指针8道速通(C++)

1. 移动零 思路&#xff1a; 拿示例1的数据来举例&#xff0c;定义两个指针&#xff0c;cur和dest&#xff0c;cur表示当前遍历的元素&#xff0c;dest以及之前表示非零元素 先用cur去找非零元素&#xff0c;每找到一个非零元素&#xff0c;就让dest的下一个元素与之交换 单个…...

synchronized锁

在了解锁之前我们要先了解对象布局 什么是java对象布局 在JVM中&#xff0c;对象在内存中存储的布局可以分为三块区域&#xff0c;即实例化之后的对象 对象头&#xff1a;分配的空间是固定的12Byte&#xff0c;由Mark Word&#xff08;标记字段&#xff09;和Class Pointer&…...

实训Day-2 流量分析与安全杂项

目录 实训Day-2-1流量分析实战 实训目的 实训任务1 SYN半链接攻击流量分析 实训任务2 SQL注入攻击流量分析一 实训任务3 SQL注入攻击流量分析二 实训任务4 Web入侵溯源一 实训任务5 Web入侵溯源二 ​编辑 实训Day-2-1安全杂项实战 实训目的 实训任务1 流量分析 FTP…...

LOH 怎么进行深度标准化?

The panel of normals is applied by replacing the germline read depth of the sample with the median read depth of samples with the same genotype in our panel. 1.解释: panel of normal 正常组织&#xff0c;用于识别技术噪音 germline read depth: 胚系测序深度。根…...