PyTorch 流水线并行模式设计分析

流水线并行(Pipeline Parallelism)最早是 Google 在 Gpipe 论文中提出的,这种并行训练模式能够充分利用多 GPU 的资源高效地训练评估大模型。目前 PyTorch 最新版本是 2.2,流水线并行的功能是基于 torchgpipe 论文中的设计来实现的,该功能当前还处于试验阶段。 问题背景 大模型无法直接放到单个 GPU 中进行训练,通过模型并行(Model Parallelism)的方法可以把模型进行分片,每一个分片放置到一个 GPU 上,这样能够很好实现模型并行且利用多 GPU 的资源。虽然使用这种较为初级的方式能够实现大模型的训练,但在训练的过程中并不能充分利用 GPU 资源,因为对顺序(Sequential)模型来说它每次只能激活一个 GPU 来进行训练,其它的 GPU 此时是闲置的,所以在底层设备上其实仍然是顺序执行。 例如,对一个有 4 层的顺序(Sequential)神经网络模型,经过模型分片后,训练过程中每一层(或 Subnetwork)放在一个 GPU 上,先进行前向传播计算得到 Loss,然后反向传播计算梯度,如下图所示: 使用这种方式利用 GPU 训练,我们可以看到在训练过程中 GPU 完全没有被充

深度学习超参数调优简介

我们知道,在深度学习中有两类基本的参数:模型参数(Model Parameters)和超参数(Hyperparameters),它们都对模型训练的结果有非常重要的影响。有些研究表明,对于超参数的选择不仅能够影响模型训练的质量好坏,而且也在一定程度上决定了模型训练需要耗费的时间以及内存资源的需求总量。甚至在一些深度模型训练过程中证明,超参数的选择比模型本身的参数更重要,影响也更大。 可见,超参数选择是否合理,直接影响了企业开发并使用模型的成本,所以在深度学习应用领域,业界已经把超参数调优作为开发深度学习应用流程中一个不可或缺的步骤。这样我们就能够把超参数调优解耦成一个独立的组件或模块,然后聚焦该组件的核心能力去做更多探索尝试,最终实现整个深度学习应用开发的业务目标,同时获得了灵活的开发模式,也具有较低的成本优势。 什么是超参数 超参数是指一类静态的参数,这些参数在模型训练之前被定义和设置,而且无法从给定的训练数据中进行学习估计。在模型训练算法中会存在很多超参数,少的话有几个,多的话可能达到几十成百上千个。下面,我们列出一

基于 PyTorch 编程使用预训练模型

使用预训练模型有两种方式:一种是直接使用得到的预训练模型进行推理,并满足应用的需要,使用起来非常简单;另一种是在预训练模型的基础上,进行微调,使得到的新模型能够更好地满足我们解决问题的需要,这种方式需要能够对模型进行调优有一定门槛。这里,我们尝试第一种方式直接使用预训练模型,着重关注使用预训练模型处理图片分类的过程,从而熟悉在实际应用中都需要做哪些处理工作。 预训练模型 预训练模型(Pre-trained Models,PTMs)是一种深度学习架构,它在大规模数据集上进行训练,以获取丰富的特征表示。训练得到的模型可以进行复用,不仅能够适用于最初要解决的问题,还可以迁移到其他类似的应用场景中,从而提高在这些新领域的应用的性能。 预训练模型通常具有较大的参数规模,需要使用海量的数据和高昂的计算资源代价,才能完成模型训练并最终得到模型参数,这对于一些不具备基于超大规模数据训练能力的使用者来说,就无法发挥模型的作用,而且也不能很方便地在特定应用领域内探索并验证一些应用的想法。 例如,在 NLP 领域,预训练模型应用的特别广

使用 PyTorch SWA 优化模型训练入门实践

PyTorch 实现了 SWA(Stochastic Weight Averaging,随机加权平均),相比于传统的 SGD,使用 SWA 能够明显改善一些深度神经网络模型的测试精度(Test Accuracy)。而且,SWA 使用起来非常简单,能够加速模型训练,并提高模型的泛化能力。 SWA 基本原理 SWA 依赖两个重要的因素: 第一个是,SWA 使用一个不断修改的 LR 调节器(Learning Rate Schedule),使得 SGD 能够在最优值附近进行调整,并评估最优解附近的值对应的模型的精度,而不是只选取最优解对应的模型。因为,最优解对应的模型不一定是最优的,而且泛化能力可能也不一定最好。比如,在 75% 的训练时间里,可以使用一个标准的衰减学习率(Decaying Learning Rate)策略,然后在剩余 25% 的训练时间里将学习率设置为一个比较高的固定值。如下图所示: 第二个是,SWA 计算的是 SGD 遍历过的神经网络权重的平均值。例如,上面提到模型训练的后 25% 时间,我们可以在这 25% 时间里的每一轮训练(every epoch)后,计算一个权重的 running 平均值,在训练结束后再设置网络模型的权重为 SWA 权重平均值。 SWA

PyTorch 使用 TensorBoard 实现可视化

在 PyTorch 中使用 TensorBoard,可以实现样本数据、模型、训练过程的可视化,能够非常直观地查看在整个训练过程中产生的效果,方便分析和解决一些问题。本文完全根据 PyTorch 官方的 TensorBoard Tutorial 文档进行实践操作,体验 TensorBoard 的基本可视化功能。 首先,需要下载 tensorboard 模块: pip3 install tensorboard 这样就可以使用 TensorBoard 了,需要通过如下命令,启动 TensorBoard 服务: tensorboard --logdir=runs 上面 runs 目录是我们写数据的目录,可以根据自己的需要设置目录名称。在使用 PyTorch 过程中需要可视化的话,就把对应的数据写入到这个目录下面的指定文件中,TensorBoard 会直接从该目录下读取并进行可视化。 启动成功后,可以打开浏览器链接 http://localhost:6006/,查看 TensorBoard UI 界面。 我们向 runs 目录中写入数据,直接使用 torch.utils.tensorboard.SummaryWriter 就可以实现,所以先要创建可用的 SummaryWriter 对象,代码如下: from torch.utils.tensorboard import SummaryWriter writer = Summar

PyTorch 分布式训练模式 FSDP 设计分析

在 AI 大模型训练场景中,数据是海量的,模型也是超大的,对于训练大模型会带来很大挑战,比如对算力的需求,对处理大模型的工程复杂度,等等。PyTorch 给出了一种实现方式——FSDP(Fully Sharded Data Parallel),它提供了易用的 API,可以非常方便地解决大模型分布式训练的难题。 FSDP 是在 DDP(DistributedDataParallel)的基础上提出的,首先我们了解一下 PyTorch 的 DDP(DistributedDataParallel) 训练模式的一些特点: 在 DDP 中,核心的能力还是训练数据并行(Data Parallel)。以多机多卡方式为例,每个 process/worker 都会持有模型的一个副本(Replica),通过使每个 process/worker 处理一个 batch 的数据试下并行处理,最后使用 all-reduce 操作对多个不同 process/worker 计算得到的梯度进行累加求和;接着,再将优化器状态、梯度通过跨多个 process/worker 进行复制,使得每个 process/worker 上的模型参数都得到同步更新。也就是说,在 DDP 中并没有实现对模型参数的分片管理,即模型并行(Model Parallel)。 在 FSDP 中实现了模型的分片管理能

使用 PyTorch 实现并训练 LeNet-5 模型

LeNet-5 是由 Yann LeCun提出的卷积神经网络,在论文《Gradient-Based Learning Applied To Document Recognition》中可以看到 LeNet-5 网络模型的结构,如下图所示: 通过上图可以看到,从左至右网络各个层顺序连接: 输入层 :图片大小 32×32 卷积层1 :输入通道 1,输出通道 6,卷积核大小 5×5,步长 1 池化层 :输入通道 6,输出通道 6,过滤器大小 2×2,步长 2 卷积层2 :输入通道 6,输出通道 16,卷积核大小 5×5, 步长 1 池化层2 :输入通道 16,输出通道 16,过滤器大小 2×2,步长 2 全连接层1:节点数 120 全连接层2:节点数 84 全连接层3:节点数 10 我们只需要准备好数据集,并基于上图连接结构,使用 PyTorch 搭建 CNN 网络的结构并进行训练和使用。 实现 LeNet-5 模型 基本环境配置如下: Python:3.11.3 PyTorch:2.0.1(torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2) 1 准备数据集 使用经典的手写数字数据集 MNIST,可以直接通过 PyTorch 的 datasets.MNIST 下载并准备数据: import torch from to

使用 PyTorch 构建机器学习应用

通过 PyTorch 官网给出的 Quickstart,了解使用 PyTorch 完成一个模型的数据准备、模型训练和评估、模型加载并应用。在实际应用中,只需要按照这个流程来编程构建即可。 下面,我们通过分步骤来说明开发机器学习应用程序的基本流程。 我们使用 PyTorch-2.0.1,安装该版本 PyTorch 执行如下命令: pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 1 准备数据 PyTorch 使用 torch.utils.data.DataLoader 和 torch.utils.data.Dataset 来实现数据的加载,并转换成包含样本和标签的 DataSet。 我们可以在 https://pytorch.org/vision/stable/datasets.html 中找到 Torchvision 提供的大量内置 DataSet,通过这些工具类就可以方便构建并使用 DataSet。如果是使用我们自己的数据集,可以继承自 torch.utils.data.Dataset 实现我们自己的 DataSet 以及 DataLoader。 这里使用了 FashionMNIST 数据集,这个数据集是一个包含时尚衣物图像,其中包括衣物图像和它们对应的标签. 首先,下载 FashionMNIST 数据集,可以直接通过 PyTorch 的 datasets API 下

Kafka SCRAM 动态认证授权配置实践

Kafka 使用 JAAS(Java Authentication and Authorization Service)来实现 SASL 认证授权。我们这里通过使用 Kafka 提供的 SCRAM 方式实现动态认证授权的配置,动态认证授权的好处非常直接,不用根据实际需求修改各种配置文件添加账号及授权,可以像操作数据库服务器一样,通过命令行就能实现认证授权的管理。 准备工作 操作系统: 我们使用 CentOS 系统,系统版本是 CentOS-7.9。 我们使用默认的单机安装方式,ZooKeeper 是内置在 Kakfa 安装包里面的,所以不需要单独下载。如果希望单独安装,可以自行准备。 为了方便操作,保证使用 ZooKeeper 的可访问性,这里直接把防火墙关闭掉: systemctl stop firewalld 下载软件: wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz wget https://archive.apache.org/dist/kafka/3.3.1/kafka_2.13-3.3.1.tgz 解压缩包: tar xzvf jdk-17_linux-x64_bin.tar.gz tar kafka_2.13-3.3.1.tgz cd kafka_2.13-3.3.1 JDK 配置这里就不累述了。 SCRAM 动态认证授权配置 基于 SCRAM 的

Stable Diffusion 模型技术架构与原理

Stable Diffusion 是一个文本到图像(txt2img)的潜在扩散模型(LDM),是由 CompVis、Stability AI 和 LAION 的研究人员实现并开源的。我们站在 Stable Diffusion 模型应用用户的角度来看,其实没有多么复杂,核心就是根据文本生成图像,其中可以通过一些技巧,或通过调整用户参数,来改变文本生成图像的过程,从而达到优化最终生成图像的目的。但是,从 Stable Diffusion 底层技术的角度看,这个过程非常非常复杂,所以我们这里先给出模型的 Architecture Overview,先从总体上看整个架构(或结构)是什么样的,然后深入到每一个部分去了解具体的技术细节和原理。 1 模型架构概览 从 High-level 的视角,Stable Diffusion 模型都包含哪些主要组件,以及整体的处理流程,我们引用了 The Illustrated Stable Diffusion 一文中的一个图,并在原图上做了微小改动(为了方便理解添加了表示三个核心步骤的数字序号),来表示 Stable Diffusion 模型的处理机制,如下图所示: 基于上图,我们分步骤描述一下 txt2image 处理的整个过程: 首先,输入 Prompt 提示词 “para

体验 Stable Diffusion 模型生成图像

Stable Diffusion 是 2022 年发布的深度学习文本到图像生成模型,是主要用于“文本生成图像”的深度学习模型,也就是常说的 txt2img 的应用场景中:通过给定文本提示词(text prompt),该模型会输出一张匹配提示词的图片。Stable Diffusion 模型能够根据文本的描述生成图像,另外它也可以应用于其他任务,如内补绘制、外补绘制,以及在提示词指导下生成图像。 Stable Diffusion 是基于“潜在扩散模型”(Latent Diffusion Model,LDM)的模型,Diffusion 是扩散的意思,通常我们简称 Stable Diffusion 模型为 SD 模型。SD 模型是开源的,我们可以在 Github 上找到它的源码和使用方法:https://github.com/Stability-AI/StableDiffusion,也可以在 Huggingface 网站上获取到相关资源:https://huggingface.co/stabilityai。 实验环境 我们实验的基础环境的基本配置,作为参考,如下所示: CentOS 7.6 64 Anaconda3-2023.07-1-Linux-x86_64 Python 3.11.3 GPU Tesla P40(显存24 G/1 core) CPU 6 vCore/56G 我们使用的 Anaconda,需要安装对应的 Python 模块:

BERT 模型架构

BERT 是 Bidirectional Encoder Representations from Transformers 的缩写,是由 Google 发布的先进的嵌入模型,BERT 是自然语言处理领域的一个重大突破,它在许多自然语言处理任务中取得了突出的成果,比如问答任务、文本生成、句子分类等。BERT 之所以能够成功,主要是因为它是基于上下文的嵌入模型,不同于像 word2vec 等其他一些流行的嵌入模型。 从 BERT 的含义来看,它使用多个 Transformer 表示,而且是基于双向 Encoder 的,我们要知道 BERT 的架构是只包含 Encoder 的 Transformer 模型架构。 BERT 模型配置 BERT 在发布模型的时候,给出了多种不同的配置,其中两种标准的配置为 BERT-base 和 BERT-large,另外还有一些小型的配置,如下表所示: BERT 模型配置 Encoder 层数(L) 注意力头个数(A) FFN 层隐藏神经元个数(H) BERT-base 12 12 768 BERT-large 24 16 1024 BERT-tiny 2 – 128 BERT-mini 4 – 256 BERT-small 4 – 512 BERT-medium 8 – 512 BERT-base 模型的网络参数总数可达 1.1 亿个,而