【深度学习】使用硬件加速模型训练速度

一、 单机器单GPU

特点
  • 配置简单:无需多 GPU 或分布式环境的复杂配置,适合资源有限的场景。
  • 适合小规模模型:对于计算量不大的模型(如中小型 CNN、RNN),单 GPU 可以处理大多数常见任务。
优势
  • 简单易用:适合深度学习初学者以及较小规模的实验。
  • 无需并行配置:仅需设置一个 GPU,代码和数据同步操作也更简单。
实现方法
  • 常用框架:可以直接在代码中指定 GPU 使用,如 TensorFlow 的 with tf.device('/GPU:0') 或 PyTorch 的 model.to('cuda')
  • 适用场景:适合开发和调试中小规模模型,以及在本地进行初步实验。

PyTorch 示例:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from torch.cuda.amp import autocast, GradScaler# 检查是否有 GPU 可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 示例模型(简单的多层感知机)
class SimpleModel(nn.Module):def __init__(self):super(SimpleModel, self).__init__()self.fc1 = nn.Linear(10, 50)self.fc2 = nn.Linear(50, 1)def forward(self, x):x = torch.relu(self.fc1(x))x = self.fc2(x)return x# 创建模型并将其加载到 GPU
model = SimpleModel().to(device)# 创建数据集和数据加载器
X = torch.randn(1000, 10)
y = torch.randn(1000, 1)
dataset = TensorDataset(X, y)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4, pin_memory=True)# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)# 训练循环
epochs = 5
for epoch in range(epochs):# 使用 PyTorch 的 AMP 自动混合精度训练scaler = GradScaler()for inputs, targets in dataloader:inputs, targets = inputs.to(device), targets.to(device)with autocast():outputs = model(inputs)loss = criterion(outputs, targets)scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()print(f"Epoch {epoch + 1}/{epochs}, Loss: {loss.item()}")
示例说明
  • dataloader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4, pin_memory=True)

    pin_memory=True 时,DataLoader 将把数据加载到页锁定内存中,使得从 CPU 到 GPU 的传输更加高效。
    并发流程:

    1. 批次准备:4 个 CPU 进程在 DataLoader 中并发从数据集加载数据,并执行数据增强、预处理,将数据固定在内存中。
    2. 数据传输:CPU 将批次数据通过 PCIe 通道传输到 GPU 的显存。
    3. GPU 执行计算:GPU 在显存中运行当前批次的前向传播和反向传播。
    4. 并发准备下一个批次:在 GPU 计算当前批次的过程中,CPU 上的 DataLoader 进程已经开始准备下一个批次数据。
    5. 重复以上过程:CPU 和 GPU 以此方式并行处理每个批次,避免 GPU 等待数据传输,提升整体训练速度。
  • amp(包含 autocastGradScaler):提供完整的混合精度训练方案,包含 autocast 的精度选择和 GradScaler 的梯度缩放,能保证训练的数值稳定性。

二、 单机器多GPU

在单台机器上配置多个 GPU,可以通过数据并行、模型并行和管道并行等策略实现多 GPU 训练。

1. 数据并行(Data Parallelism)

数据并行是最常用的多 GPU 训练策略,将数据划分到不同的 GPU 上,并在每个 GPU 上独立地计算前向传播和反向传播。每个 GPU 得到的梯度会在同步步骤中合并,更新全局模型参数。

  • 工作流程
    1. 将批次数据划分到不同的 GPU 上。
    2. 每个 GPU 独立计算前向和反向传播,生成局部梯度。
    3. 汇总所有 GPU 的梯度,更新全局模型参数。
  • 适用场景:适合数据量大、模型规模适中的场景,是目前最常用的并行训练方式。
代码示例

PyTorch提供了多种方式来实现多GPU训练,常用的方法是使用 torch.nn.DataParalleltorch.nn.parallel.DistributedDataParallel

    1. 使用 torch.nn.DataParallel

DataParallel 是一种简单直接的多GPU训练方法,适合小规模的多GPU训练任务。它会自动将数据分配到多个GPU上,并将每个GPU的输出合并。

import torch
import torch.nn as nn
from torch.utils.data import DataLoader# 定义模型
model = MyModel()# 将模型包装成多GPU模型
if torch.cuda.device_count() > 1:print(f"使用 {torch.cuda.device_count()} 个 GPU 进行训练")model = nn.DataParallel(model)# 将模型移动到GPU
model = model.cuda()# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())# 加载数据
dataset = MyDataset()
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)# 训练循环
for epoch in range(num_epochs):for data, target in dataloader:data, target = data.cuda(), target.cuda()# 前向传播output = model(data)loss = criterion(output, target)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}")
    1. 使用 torch.nn.parallel.DistributedDataParallel

DistributedDataParallel (DDP) 是一种更高效的分布式训练方式,推荐在多GPU和分布式训练任务中使用,尤其适合更大规模的训练。

在单机器多GPU的情况下,也可以用DDP,它会在每个GPU上启动一个进程来进行并行计算。以下是使用DDP的代码示例。

设置DDP的关键步骤
  1. 设置进程组:使用 torch.multiprocessing 来启动多个进程,每个进程对应一个GPU。
  2. 初始化DDP模型:用 DistributedDataParallel 包装模型。
  3. 数据划分:使用 DistributedSampler 来分配数据到不同的进程。
  4. 运行代码:需通过torch.multiprocessing.spawn启动多进程。或者直接使用torchrun 命令启动脚本python -m torchrun --nproc_per_node=NUM_GPUS_YOU_HAVE your_script.py --arg1 --arg2
import torch
import torch.nn as nn
import torch.multiprocessing as mp
import torch.distributed as dist
from torch.utils.data import DataLoader, DistributedSampler# 初始化进程函数
def train(rank, world_size):# 初始化进程组dist.init_process_group("nccl", rank=rank, world_size=world_size)torch.cuda.set_device(rank)# 定义模型,并移动到相应GPUmodel = MyModel().to(rank)model = nn.parallel.DistributedDataParallel(model, device_ids=[rank])# 定义损失函数和优化器criterion = nn.CrossEntropyLoss().to(rank)optimizer = torch.optim.Adam(model.parameters())# 创建数据集和分布式采样器dataset = MyDataset()sampler = DistributedSampler(dataset, num_replicas=world_size, rank=rank, shuffle=True)dataloader = DataLoader(dataset, batch_size=32, sampler=sampler)# 训练循环for epoch in range(num_epochs):sampler.set_epoch(epoch)  # 每个epoch设定不同的采样for data, target in dataloader:data, target = data.to(rank), target.to(rank)# 前向传播output = model(data)loss = criterion(output, target)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if rank == 0:  # 只在主进程上打印print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}")# 清理进程组dist.destroy_process_group()# 主函数
if __name__ == "__main__":world_size = torch.cuda.device_count()  # 获取可用GPU数量mp.spawn(train, args=(world_size,), nprocs=world_size, join=True)
解释
  • train 函数中包含了每个进程需要执行的代码,rank表示每个GPU对应的编号。
  • DistributedDataParallel 在每个GPU上创建一个独立的模型副本,且 device_ids 参数指定了每个模型副本运行的设备。
  • DistributedSampler 将数据分配给每个进程,以确保在多进程中数据不会重复。
2. 模型并行(Model Parallelism)

模型并行是指将模型的不同部分分配到不同的 GPU 上,每个 GPU 只负责一部分模型的计算。这种方法适合非常大的模型,单个 GPU 无法容纳所有参数时使用。

  • 工作流程
    1. 将模型划分成多个子部分(如按层或模块)。
    2. 数据在 GPU 间传递,每个 GPU 负责一个模型部分的前向和反向传播。
  • 适用场景:适合超大规模模型(如 GPT-3),在单个 GPU 内存不足以容纳全部参数时使用。
3. 管道并行(Pipeline Parallelism)

管道并行是一种结合数据并行和模型并行的方式,将模型分成多个阶段,数据分批次流经每个阶段的不同 GPU,从而在多个 GPU 之间形成“流水线”。

  • 工作流程
    1. 将模型按层次或功能模块划分成多个阶段,每个阶段在不同的 GPU 上。
    2. 数据逐批通过每个阶段的 GPU,同时保持并行计算。
  • 适用场景:适合具有分层结构的模型,尤其在超大批次的训练任务中提升效率。

三、多机器多GPU

在分布式训练中,模型可以跨越多台机器(节点)进行训练,每个节点可以有一个或多个 GPU。分布式训练的核心在于如何在各节点之间有效地通信和同步梯度。

1. 分布式数据并行(Distributed Data Parallelism)

分布式数据并行是分布式训练中最常用的模式,它与单机器多GPU 的数据并行类似,但在不同机器的 GPU 间进行并行计算。每台机器上会有一个完整的模型副本,训练数据在所有机器间分布。

  • 梯度同步:常用的梯度同步方法是全归约(All-Reduce),它在每个节点中同步并合并梯度更新。
  • 实现框架
    • PyTorch Distributed Data Parallel (DDP):使用 PyTorch 自带的 DDP 模块,可实现多节点的分布式训练,适合在多 GPU 集群中。
    • TensorFlow MirroredStrategy:TensorFlow 的 tf.distribute.MirroredStrategy 支持多 GPU、单机多 GPU 和多机多 GPU 的训练。
    • Horovod:Uber 开发的分布式训练框架,支持 TensorFlow、Keras 和 PyTorch,使用环形 All-Reduce 方式进行高效的梯度同步。
  • 适用场景:适合数据量大且可分割的大批量训练任务。
DDP示例
import os
import torch
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel as DDP
from torch.utils.data import DataLoader, DistributedSampler
from torchvision import datasets, transforms# 定义模型
class MyModel(torch.nn.Module):def __init__(self):super(MyModel, self).__init__()self.fc = torch.nn.Linear(784, 10)def forward(self, x):return self.fc(x.view(-1, 784))# 训练函数
def train():# 从环境变量中获取 rank 和 world_sizerank = int(os.environ["RANK"])world_size = int(os.environ["WORLD_SIZE"])# 初始化分布式进程组dist.init_process_group(backend="nccl",init_method="env://",rank=rank,world_size=world_size)# 获取当前节点的 GPU 数量local_rank = rank % torch.cuda.device_count()torch.cuda.set_device(local_rank)# 创建模型并移动到对应的 GPU 上model = MyModel().to(local_rank)model = DDP(model, device_ids=[local_rank])# 定义损失函数和优化器criterion = torch.nn.CrossEntropyLoss().to(local_rank)optimizer = torch.optim.SGD(model.parameters(), lr=0.01)# 数据加载器,使用 DistributedSampler 分配数据transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)sampler = DistributedSampler(dataset, num_replicas=world_size, rank=rank, shuffle=True)dataloader = DataLoader(dataset, batch_size=64, sampler=sampler)# 训练循环for epoch in range(10):sampler.set_epoch(epoch)for batch_idx, (data, target) in enumerate(dataloader):data, target = data.to(local_rank), target.to(local_rank)# 前向传播optimizer.zero_grad()output = model(data)loss = criterion(output, target)# 反向传播和优化loss.backward()optimizer.step()if batch_idx % 100 == 0 and rank == 0:  # 仅主进程打印日志print(f"Epoch [{epoch+1}/10], Step [{batch_idx}/{len(dataloader)}], Loss: {loss.item():.4f}")# 清理进程组dist.destroy_process_group()if __name__ == "__main__":train()

在使用 torchrun 启动分布式训练时,torchrun 会自动计算和设置 RANKWORLD_SIZE 环境变量,这样每个进程都能知道其在分布式系统中的全局位置。这是 torchrun 的一个重要特性,帮助简化分布式训练的设置流程。

解释

torchrun 使用以下命令行参数来推断和设置这些环境变量:

  • --nnodes:指定分布式系统中的总节点(机器)数量。
  • --nproc_per_node:指定每台机器上启动的进程数量(通常等于 GPU 数量)。
  • --node_rank:指定当前机器的节点编号(从 0 开始),用于确定当前机器的 RANK 起始位置。
  • --master_addr--master_port:指定主节点的 IP 地址和端口,确保所有节点可以连接到主节点进行通信。

torchrun 根据这些参数计算并设置 WORLD_SIZERANK,每个进程启动时就能自动获得这些环境变量。

  • WORLD_SIZE:全局进程数,即分布式系统中的总进程数。
  • RANK:每个进程的全局唯一编号,用来标识当前进程在整个分布式系统中的位置。
    • 每台机器上的 RANK 是按顺序递增的,从主节点开始。
    • 例如,如果有两台机器,每台机器启动 4 个进程,那么 RANK 在主节点(node_rank=0)上为 0-3,在第二台机器(node_rank=1)上为 4-7

假设有两台机器,每台机器上分别有 4 个 GPU,配置如下:

    1. 主节点(机器 1)启动命令:
torchrun --nnodes=2 --nproc_per_node=4 --node_rank=0 --master_addr="<主节点IP地址>" --master_port="12355" script.py
  • WORLD_SIZE 自动设置为 2 * 4 = 8

  • RANK 自动为 0-3,对应机器 1 上的 4 个进程。

    1. 第二台机器(机器 2)启动命令:
torchrun --nnodes=2 --nproc_per_node=4 --node_rank=1 --master_addr="<主节点IP地址>" --master_port="12355" script.py
  • WORLD_SIZE 仍为 8
  • RANK 自动为 4-7,对应机器 2 上的 4 个进程。
注意

torchrun 不支持不同的 nproc_per_node,我们需要手动启动每个机器的进程,确保每个进程的 RANK 和 WORLD_SIZE 环境变量设置正确。
假设我们有两台机器,且每台机器上 GPU 数量不同:机器 1有 4 个 GPU,机器 2有 2 个 GPU。

主节点(机器 1)启动命令:

# 启动第一个进程
RANK=0 torchrun --nproc_per_node=1 --nnodes=2 --node_rank=0 --master_addr="<主节点IP地址>" --master_port="12355" --world_size=6 script.py &# 启动第二个进程
RANK=1 torchrun --nproc_per_node=1 --nnodes=2 --node_rank=0 --master_addr="<主节点IP地址>" --master_port="12355" --world_size=6 script.py &# 启动第三个进程
RANK=2 torchrun --nproc_per_node=1 --nnodes=2 --node_rank=0 --master_addr="<主节点IP地址>" --master_port="12355" --world_size=6 script.py &# 启动第四个进程
RANK=3 torchrun --nproc_per_node=1 --nnodes=2 --node_rank=0 --master_addr="<主节点IP地址>" --master_port="12355" --world_size=6 script.py &

第二台机器(机器 2)启动命令:

export WORLD_SIZE=6# 启动第一个进程
RANK=4 torchrun --nproc_per_node=1 --nnodes=2 --node_rank=1 --master_addr="<主节点IP地址>" --master_port="12355" --world_size=6 script.py &# 启动第二个进程
RANK=5 torchrun --nproc_per_node=1 --nnodes=2 --node_rank=1 --master_addr="<主节点IP地址>" --master_port="12355" --world_size=6 script.py &
2. 分布式模型并行(Distributed Model Parallelism)

分布式模型并行将模型拆分到不同节点的 GPU 上,通常用于单节点 GPU 无法容纳完整模型的超大规模模型(如 GPT-3)。

  • 参数分配:模型参数按功能模块或层次划分到不同的 GPU。
  • 前向与反向传播:每个 GPU 只计算自己负责的部分,然后将输出传递给下一层的 GPU。
  • 适用场景:适用于超大模型的训练(如 Transformer、大规模语言模型等),尤其在内存受限时。
3. 混合并行(Hybrid Parallelism)

混合并行结合数据并行和模型并行的优势,用于训练规模极大的模型。可以同时在不同 GPU 上进行数据并行训练,并在每个 GPU 内部按模型并行分配参数。

  • 实现框架
    • Megatron-LM:NVIDIA 提供的框架,支持混合并行训练超大规模 Transformer 模型。
    • DeepSpeed:微软开发的分布式训练优化库,支持数据并行、模型并行、流水线并行以及零冗余优化。
  • 适用场景:超大规模模型的训练,适合在分布式多 GPU 集群中实现。

四、TPU(张量处理单元)

TPU 是 Google 专门为深度学习设计的硬件加速器,尤其针对矩阵运算进行了优化。

TPU 的特点
  • 高度优化的矩阵运算:TPU 专为深度学习而设计,适合卷积神经网络(CNN)和循环神经网络(RNN)等高密度计算任务。
  • 高内存带宽:TPU 拥有很高的内存带宽,可以加速训练过程中数据的加载和计算。
使用 TPU 的方法
  • Google Colab 和 Google Cloud Platform(GCP):可以在 Google Colab 免费使用 TPU,GCP 提供的 TPU 资源适合更大规模任务。
  • TensorFlow 高效兼容:TPU 最适合 TensorFlow 框架的使用,Keras 和 TensorFlow 可以在单行代码中切换 TPU 支持。
TPU 使用场景
  • Transformer 模型:如 BERT、GPT 等 NLP 模型。
  • 大规模深度神经网络:适合需要更大数据处理能力的深度神经网络。

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

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

相关文章

解决Windows远程桌面 “为安全考虑,已锁定该用户账户,原因是登录尝试或密码更改尝试过多。请稍后片刻再重试,或与系统管理员或技术支持联系“问题

当我们远程连接服务器连接不上并提示“为安全考虑&#xff0c;已锁定该用户账户&#xff0c;原因是登录尝试或密码更改尝试过多。请稍候片刻再重试&#xff0c;或与系统管理员或技术支持联系”时&#xff0c;根本原因是当前计算机远程连接时输入了过多的错误密码&#xff0c;触…

Cyberchef配合Wireshark提取并解析TCP/FTP流量数据包中的文件

前一篇文章中讲述了如何使用cyberchef提取HTTP/TLS数据包中的文件,详见《Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件》,链接这里,本文讲述下如何使用cyberchef提取FTP/TCP数据包中的文件。 FTP 是最为常见的文件传输协议,和HTTP协议不同的是FTP协议传输…

vs2022搭建opencv开发环境

1 下载OpenCV库 https://opencv.org/ 下载对应版本然后进行安装 将bin目录添加到系统环境变量opencv\build\x64\vc16\bin 复制该路径 打开高级设置添加环境变量 vs2022新建一个空项目 修改属性添加头文件路径和库路径 修改链接器&#xff0c;将OpenCV中lib库里的o…

构建SSH僵尸网络

import argparse import paramiko# 定义一个名为Client的类&#xff0c;用于表示SSH客户端相关操作 class Client:# 类的初始化方法&#xff0c;接收主机地址、用户名和密码作为参数def __init__(self, host, user, password):self.host hostself.user userself.password pa…

【开源免费】基于SpringBoot+Vue.JS购物推荐网站(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 073 &#xff0c;文末自助获取源码 \color{red}{T073&#xff0c;文末自助获取源码} T073&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

PG-DERN 解读:少样本学习、 双视角编码器、 关系图学习网络

本文提出了一种用于 分子属性预测 的 少样本学习&#xff08;Few-shot Learning&#xff09; 模型—— PG-DERN&#xff0c;该模型结合了 双视角编码器&#xff08;Dual-view Encoder&#xff09; 和 关系图学习网络&#xff08;Relation Graph Learning Network&#xff09; 双…

RabbitMQ-死信队列(golang)

1、概念 死信&#xff08;Dead Letter&#xff09;&#xff0c;字面上可以理解为未被消费者成功消费的信息&#xff0c;正常来说&#xff0c;生产者将消息放入到队列中&#xff0c;消费者从队列获取消息&#xff0c;并进行处理&#xff0c;但是由于某种原因&#xff0c;队列中的…

Uni-APP+Vue3+鸿蒙 开发菜鸟流程

参考文档 文档中心 运行和发行 | uni-app官网 AppGallery Connect DCloud开发者中心 环境要求 Vue3jdk 17 Java Downloads | Oracle 中国 【鸿蒙开发工具内置jdk17&#xff0c;本地不使用17会报jdk版本不一致问题】 开发工具 HBuilderDevEco Studio【目前只下载这一个就…

Python中的with语句

with语句和上下文管理器 Python提供了 with 语句的写法&#xff0c;既简单又安全 文件操作的时候使用with语句可以自动调用关闭文件操作&#xff0c;即使出现异常也会自动关闭文件操作。 # 1、以写的方式打开文件 with open(1.txt, w) as f:# 2、读取文件内容f.write(hello wor…

SQL面试题——抖音SQL面试题 主播播出时长

主播播出时长 现有如下数据,主播id、房间号、播出的批次号,每个批次号进出房间的时间戳、分区时间: 每一次直播都有一个上播和下播,每个房间里,同一个批次号会有两条数据,分别记录了上播和下播时间,求每个主播的播出时长? 通过上面的数据,可以清晰的看出,同一个批次…

【汇编】c++游戏开发

由一起学编程创作的‘C/C项目实战&#xff1a;2D射击游戏开发&#xff08;简易版&#xff09;&#xff0c; 440 行源码分享来啦~’&#xff1a; C/C项目实战&#xff1a;2D射击游戏开发&#xff08;简易版&#xff09;&#xff0c; 440 行源码分享来啦~_射击c-CSDN博客文章浏览…

Uniapp 引入 Android aar 包 和 Android 离线打包

需求&#xff1a; 原生安卓 apk 要求嵌入到 uniapp 中&#xff0c;并通过 uniapp 前端调起 app 的相关组件。 下面手把手教你&#xff0c;从 apk 到 aar&#xff0c;以及打包冲突到如何运行&#xff0c;期间我所遇到的问题都会 一 一 进行说明&#xff0c;相关版本以我文章内为…

自动化运维(k8s):一键获取指定命名空间镜像包脚本

前言&#xff1a;脚本写成并非一蹴而就&#xff0c;需要不断的调式和修改&#xff0c;这里也是改到了7版本才在 生产环境 中验证成功。 该命令 和 脚本适用于以下场景&#xff1a;在某些项目中&#xff0c;由于特定的安全或政策要求&#xff0c;不允许连接到你的镜像仓库。然而…

Vue2+ElementUI:用计算属性实现搜索框功能

前言&#xff1a; 本文代码使用vue2element UI。 输入框搜索的功能&#xff0c;可以在前端通过计算属性过滤实现&#xff0c;也可以调用后端写好的接口。本文介绍的是通过计算属性对表格数据实时过滤&#xff0c;后附完整代码&#xff0c;代码中提供的是死数据&#xff0c;可…

机器学习(1)

一、机器学习 机器学习&#xff08;Machine Learning, ML&#xff09;是人工智能&#xff08;Artificial Intelligence, AI&#xff09;的一个分支&#xff0c;它致力于开发能够从数据中学习并改进性能的算法和模型。机器学习的核心思想是通过数据和经验自动优化算法&#xff…

【Linux学习】【Ubuntu入门】1-4 ubuntu终端操作与shell命令1

1.使用快捷键CtrlAltT打开命令终端&#xff0c;或者单击右键点击… 2.常用shell命令 目录信息查看命令&#xff1a;ls ls -a&#xff1a;显示目录所有文件及文件夹&#xff0c;包括隐藏文件&#xff0c;比如以.开头的 ls -l&#xff1a;显示文件的详细信息 ls -al&#xff1…

Oracle OCP认证考试考点详解082系列19

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 91. 第91题&#xff1a; 题目 解析及答案&#xff1a; 关于 Oracle 数据库中的索引及其管理&#xff0c;以下哪三个陈述是正确的&#x…

智能网页内容截图工具:AI助力内容提取与可视化

我们每天都会接触到大量的网页内容。然而&#xff0c;如何从这些内容中快速提取关键信息&#xff0c;并有效地进行整理和分享&#xff0c;一直是困扰我们的问题。本文将介绍一款我近期完成的基于AI技术的智能网页内容截图工具&#xff0c;它能够自动分析网页内容&#xff0c;截…

基于单片机智能温室大棚监测系统

本设计以单片机为核心的智能温室大棚监测系统&#xff0c;用于监测大棚内的温湿度、土壤湿度、CO2浓度和光照强度。该系统以STM32F103C8T6芯片为核心控制单元&#xff0c;涵盖电源、按键、NB-IoT模块、显示屏模块、空气温湿度检测、土壤湿度检测、二氧化碳检测和光敏电阻等模块…

深挖C++赋值

详解赋值 const int a 10; int b a;&a 0x000000b7c6afef34 {56496} &a 0x000000b7c6afef34 {10} 3. &b 0x000000b7c6afef54 {10} 总结&#xff1a; int a 10 是指在内存中&#xff08;栈&#xff09;中创建一个int &#xff08;4 byte&#xff09;大小的空间…