AI、极客音频学习知识点

极客时间《Linux 性能优化实战》案例 git,以及相应的博客课程
Java 并发编程实战–王宝令
Java 性能调优实战
B站:AI System & AI Infra(zomi酱)
B站李沐老师论文精读

论文阅读

Gpipe:流水线并行,将模型多层均分放在不同的卡上,然后每一批次的数据训练时,再切分成多个mini-batch(一般要为卡的4倍大小),这样就可以提升多卡并行执行的效率(否则,整个过程就一个batch,0卡执行时,其他卡等待,0卡执行完,1卡执行,而其他所有卡都空闲,…)。计算过程中,不保留中间变量(激活函数得到的数值),反向传播更新梯度时,再重新计算一次forward(占整个真实计算的1/3)。这是算力换内存的思想!!!以此获取更多的显存,从而增大mini-batch大小。

Megatron-LM:张量并行(只适用于Transformer模型上)

大模型相关岗位技术要求

大模型网络:Bert、Transformer、GPT、SwitchTransformer
大模型训练框架:DeepSpeed Megatron、TensorRT-LLM
大模型微调方法:常见的几种微调方法
大模型推理计算库:Flash Attention、Paged Attention、FastTransformer、Byte-Transformer
大模型推理平台:TensorRT
大模型分布式训练技术:大模型分布式训练技术PS(Parameter Server,参数服务器)

MoE技术

B站MoE视频讲解
MoE

GPU知识相关

GPU基础知识
GPU的存储结构类似CPU一样,也可以分层3层,DRAM、HBM、SRAM(内存由高到底,访问速度由低到高)在这里插入图片描述
如上图所示,在A100 GPU有40-80GB的高带宽内存(HBM,它是由多个DRAM堆叠出来的),带宽为1.5-2.0 TB/s,而每108个流处理器(SM)有192KB的SRAM,带宽估计在19TB/s左右。

一方面,从上面的数字可以看出SRAM的访问速率是HBM的10倍左右,然而其能承载的数据量却远远小于HBM。

在GPU的编程架构中,最小的执行单元为warp(即为固定大小的线程束,一般为32个线程为一个warp,它们在同一个时钟周期内并行执行相同的指令),warp是SM中的调度单元,不同的warp在计算时会从SRAM中读取计算所需的数据(即共享存储寄存器)。

它对应的是编程架构中的block,一个SM可以包含多个Block,每个Block可以包含多个线程束Warp,但是Block不能跨SM。

当计算所依赖的数据量较大需要跨SM时访问时,则会从更下级的HBM存储器中拷贝数据进行计算。

它对应的是编程架构中的Grid,其能控制访问HBM显存。

其次,在CUDA编程框架中提供了从HBM拷贝到SRAM的计算原语,我们可以指定部分数据拷贝在SRAM中进行计算。

flashAttention 就是基于GPU内存结构对Transformer进行优化的。在这里插入图片描述

大模型推理并行技术

大模型的并行切分方式对通信和时延的要求:

切分方式通信操作通信量级(单卡)时延要求集群部署方式要求
Tensor并行AllReduce百GB秒级节点内
流水线并行Send/RecvMB秒级节点间
数据并行AllReduceGB十秒级节点内/间
优化器并行Allgather/reduce scatter百GB秒级节点内
专家并行All2All百GB秒级高网络吞吐

数据并行流水线并行对节点间的带宽要求较低;但专家并行(MOE的并行技术EP),需要节点间较高的带宽才可以支持。

大模型LLM推理相关技术

  • 投机推理
  • KV cache
  • Continuous batching
  • Paged Attention (PA)
  • Flash Attention (FA)
    FA相关讲解

大模型微调技术

大模型技术栈

1、模型设计:将问题转化为对应的大模型,模型框架的选择与设计;
2、训练作业:GPU,NPU,学习率,batch size,初始化,优化器等;
3、学习策略:监督学习,无监督学习,强化学习等;
4、分布式框架;
5、SFT;
6、分布式优化、内存优化、算子加速、集群组网;
7、高性能存储、高可靠集群;

硬件通信方式

机器内通信:共享内存、PCIe(GPU与CPU之间)、NVLink(GPU与GPU之间);
机器间通信:TCP/IP网络、RDMA网络(AI框架常用的)
RDMA:远程内存直连,有以下3个重要特性

  1. CPU offload:无需CPU干预,远程主机CPU缓存cache不会被访问的内存内存所填充;
  2. kernel bypass:专有verbs interface,应用程序可以直接在用户态执行数据传输;
  3. zero copy:每个应用程序都能直接访问集群中的设备的虚拟内存;

软件通信协调

  1. MPI:定义了多个原语的消息传递接口,这一接口主要被用于多进程间的通信。MPI系统通信方式是建立在点对点通信之上。而集合通讯是建立在端到端通信的基础上,在一组进程内的通讯原语。
  2. NCCL/HCCL:NVIDIA和华为的
  3. Gloo

通信实现方式

点对点通信Send/Recv:TCP/IP,RDMA
集合式通信All Reduce:TCP/IP,NCCL

  1. 一对多:Scatter / Broadcast
    Broadcast:某个节点想把自身的数据发送到其他节点,那么就可以使用广播机制。分布式机器学习中常用于网络参数的初始化
    Scatter :将主节点的数据进行划分并散布至其他指定的节点
  2. 多对一:Gather / Reduce
    Reduce:一系列简单运算操作的统称,细分可以包括sum、min、max、prod、lor等类型的规约操作;
    Gather :将多个Sender上的数据收集到单节点上,可以理解为反向的Scatter
  3. 多对多:All Reduce / All Gather
    All Reduce:在所有的节点上都应用同样的reduce操作
    All Gather:收集所有数据到所有节点上。发送多个数据到多个节点很有用,即在多对多通信模式的场景。

大模型性能调优工具:profiler

在这里插入图片描述

Tensor切分、变形等方法

  1. Tensor的链接操作
    cat
torch.cat(tensors, dim = 0, out = None)

stack

torch.stack(inputs, dim=0)
  1. Tensor的切分操作
torch.chunk(input, chunks, dim=0)

torch.split(tensor, split_size_or_sections, dim=0)

torch.unbind(input, dim=0)

Pytorch矩阵转秩

在PyTorch中有两个函数,分别是permute()和transpose()可以用来实现矩阵的转秩,或者说交换不同维度的数据。比如在调整卷积层的尺寸、修改channel的顺序、变换全连接层的大小的时候,我们就要用到它们。

>>> x = torch.rand(2,3,5)
>>> x.shape
torch.Size([2, 3, 5])
>>> x = x.permute(2,1,0)
>>> x.shape
torch.Size([5, 3, 2])

>>> x.shape
torch.Size([2, 3, 4])
>>> x = x.transpose(1,0)
>>> x.shape
torch.Size([3, 2, 4])

需要注意的是,经过了transpose或者permute处理之后的数据,变得不再连续了
还是接着刚才的例子说,我们使用torch.rand(2,3,4)得到的tensor,在内存中是连续的,但是经过transpose或者permute之后呢,比如transpose(1,0),内存虽然没有变化,但是我们得到的数据“看上去”是第0和第1维的数据发生了交换,现在的第0维是原来的第1维,所以Tensor都会变得不再连续。

Pytorch形状变换

在PyTorch中有两种常用的改变形状的函数,分别是view和reshape。

>>> x = torch.randn(4, 4)
>>> x.shape
torch.Size([4, 4])
>>> x = x.view(2,8)
>>> x.shape
torch.Size([2, 8])
>>> x = x.permute(1,0)
>>> x.shape
torch.Size([8, 2])
>>> x.view(4, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.

结合代码可以看到,利用permute,我们将第0和第1维度的数据进行了变换,得到了[8, 2]形状的Tensor,在这个新Tensor上进行view操作,忽然就报错了,为什么呢?其实就是因为view不能处理内存不连续Tensor的结构

那这时候要怎么办呢?我们可以使用另一个函数,reshape:

>>> x = x.reshape(4, 4)
>>> x.shape
torch.Size([4, 4])

这样问题就迎刃而解了。其实reshape相当于进行了两步操作,先把Tensor在内存中捋顺了,然后再进行view操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值