Skip to content

Latest commit

 

History

History
124 lines (107 loc) · 11.7 KB

File metadata and controls

124 lines (107 loc) · 11.7 KB

GPU

GPU采用了数量众多的计算单元和超长的流水线,但只有非常简单的控制逻辑并省去了Cache。而CPU不仅被Cache占据了大量空间,而且还有有复杂的控制逻辑和诸多优化电路,相比之下计算能力只是CPU很小的一部分,cpu主要是用于做复杂运算的

flops:每秒所执行的浮点运算次数,评估的是fpu的执行速度 吞吐量:单位时间内成功处理的运算数量,通常为gflops 带宽:单位时间内可处理的数据量,通常为MB/s或GB/s 延迟:一个操作从开始到完成的时间,常用微秒us

硬件设计师,在两个不同的方向设置gpu和cpu,主要是为了平衡带宽和算力的差异 cpu的带宽很难跑过运算速度,数据读取的延迟是非常高的 GPU上层提供的语言主要有图像编程和并行计算

CPU和GPU架构对比

线程数gpu是比cpu多的,gpu的寄存器是比cpu多的,多寄存器可以支撑多线程,线程需要用到寄存器,线程数目大寄存器也要大 gpu的SIMD单元也是比cpu多的,SIMD可以实现以同步方式在同一时间执行同一条指令

CPU和GPU不同

设计目标

  1. GPU设计目标是最大化吞吐量(Throughout),比单任务执行快慢,更关心并行度(parallelism),即同时可以执行多少任务;CPU则更关心延迟(latency)和并发(concu rrency)
  2. CPU和GPU之所以大不相同,是由于其设计目标的不同,它们分别针对了两种不同的应用场景。CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂。而GPU面对的则是类型高度统一的、相互无依赖的大规模数据和不需要被打断的纯净的计算环境。
  3. GPU拥有非常多的线程,为大量大规模的任务并行而设计的(大型的吞吐器,一部分线程在等待数据,一部分等待被激活计算,一部分正在计算过程中),硬件设计师将硬件资源都投入到增加更多的线程中,而不是想减少数据搬运和指令执行的延迟;CPU是希望在一个线程中完成所有的工作,而且不是通过增加线程解决问题,使用相反方式,通过优化线程执行的速率和效率

CPU组成及说明

==CPU是基于低延时的设计==

  • ALU:有很强大的ALU(算数运算单元),可以在很少时钟周期内完成算术运算
  • Cache:大的缓存也可以降低延时,保存很多的数据在缓存中
  • 复杂控制单元:当程序含有多个分支的时候,它通过提供分支预测的能力来降低延时。
    • 数据转发:当一些指令依赖前面的指令结果时,数据转发的逻辑控制单元决定这些指令在pipeline中的位置并且尽可能快的转发一个指令的结果给后续的指令。这些动作需要很多的对比电路单元和转发电路单元。

GPU组成及说明

==GPU是基于大的吞吐量设计== GPU是基于SIMT架构,其主体由多个相同的流式多处理器组成,因此具有高并发度的特点 GPU有很多的ALU和很少的cache,和cpu不同的是,Cache缓存的目的不是保存后续需要访问的数据,而是为线程的提高服务的,为后续的数据访问提供转发的角色,;

  • 数据转发:如果有多个线程需要访问同一个相同数据,cache缓存会合并访问,再转发访问DRAM,获取数据后,cache会转发这个数据给对应线程,但是由于需要访问dram,自然会带来延时的问题
  • DRAM访问延时:虽然有dram延时,但GPU也有非常多的ALU和多的thread,主要也是为了平衡内存访问延迟的问题。 我们可以充分利用多个ALU的特性,达到一个非常大的吞吐量的效果,尽可能多的分配多个线程,所以GPU会有很重的pipline

其他

CPU核心比较重,常用来处理非常复杂的控制逻辑,优化串行复杂运算程序执行,通用性要求很高 GPU核心比较轻,常用于优化具有简单控制逻辑的数据并行任务,注重并行程序的吞吐量,擅长大规模并发计算 但如果有些任务涉及到流动问题,一个执行完才可以执行下一个(即任务存在依赖关系),这种就需要CPU来做

什么类型的程序适合在GPU上运行?

(1)计算密集型的程序。所谓计算密集型(Compute-intensive)的程序,就是其大部分运行时间花在了寄存器运算上,寄存器的速度和处理器的速度相当,从寄存器读写数据几乎没有延时。可以做一下对比,读内存的延迟大概是几百个时钟周期;读硬盘的速度就不说了,即便是SSD, 也实在是太慢了。 (2)易于并行的程序。GPU其实是一种SIMD(Single Instruction Multiple Data)架构, 他有成百上千个核,每一个核在同一时间最好能做同样的事情。

什么是ALU和流水线?

  • ‌ALU(算术逻辑单元)‌ 是GPU和CPU中执行算术(如加、减)和逻辑(如与、或、非)运算的核心部件 ‌11。
  • 流水线(Pipeline) 是一种通过将指令处理过程分解为多个阶段(如取指、译码、执行、写回),使多条指令可以并行处理的技术,从而提升效率

指令与数据有哪些分类?

SISD:就是传统意义上的串行;最大优势是CPU上进行编码时,程序员可以按串行逻辑思考,但对并行操作、并行加速和其他细节则用编译器负责 SIMD:指令流并发的广播到多处理器上,每个处理器拥有各自的数据流,处理器内存只需要一套逻辑来对这个指令流进行解码和执行,而无需多个指令通道。但也有两个痛点((1)高级语言不好支持;(2)不灵活,如不能实现只计算特定部分 ),但后续的SIMT可以解决这两个痛点 MIMD:每个处理单元拥有自己的指令流,并且这些指令流操作自己的数据流,大部分并行系统的类型

GPU架构

整体包含关系:GPC(图像处理簇)>TPC(纹理处理簇)>SM(流多处理器)>CORE()

SM

SM组件:CUDA核心(也成为SP)、共享内存、寄存器等。SM包含许多为线程执行数学运算的Core,是 NVIDA 的核心。 SP演进:SP>>CUDA核心>>FP32和INT32 ALU SM通过Cache或Register去约束每个块线程的大小 SM&Warp说明:

CUDA

CUDA是一种并行计算架构和编程模型,可以让我们方便控制GPU各种并行的硬件,

  • CUDA核心与CPU核心主要区别是:SIMD(单指令多数据,可以使同一个指令逻辑运行对多个CUDA核心计算)
  • NPU与GPU的主要区别是:在于乘加器的排列组合,以及改变数据流动方式,不需要再运回缓存

线程层次结构

包含关系:Grad>Block>Thread

  1. Grad网格
    1. kernel在 device 上执行时实际上是启动很多线程,一个 kernel 所启动的所有线程称为一个网格(grid )
    2. 同一个网格上的线程共享相同的全局内存空间。grid是线程结构的第一层次。
  2. Block块
    1. Grid 分为多个线程块(block),一个个 block 里面包含很多线程。
    2. Block 间并行执行,并且无法通信,也没有执行顺序。
    3. 每个 block 包含共享内存(Shared Memory),可以里面的 Thread 共享。
  3. Thread线程
    1. CUDA 并行程序,实际上会被多个 threads 来执行;
    2. 多个 threads 会被群组成一个线程 block;
    3. 同一个 block 中 threads 可以同步,也可以通过 shared memory 通信。

核Kernel

  1. CUDA 执行流程中最重要的一个过程是调用CUDA的核函数来执行并行计算,kernel是CUDA中个重要的概念。
  2. 在 CUDA 程序架构中,Host 代码部分在CPU上执行,是普通C代码;当遇到数据并行处理的部分,CUDA就会将程序编译成GPU能执行的程序,并传送到GPU,这个程序在CUDA里称做核(kernel )
  3. Device 代码部分在 GPU 上执行,此代码部分在 kernel 上编写(.cu文件)。kernel用__global__符号声明,在调用时需要用<<<grid,block>>>来指定kernel要执行及结构。

CUDA 架构设计

  1. 主设概念:CUDA引入主机端(host)和设备(device)概念CUDA 程序中既包含host程序,又包含device程序。
  2. 互相通信:host与device之间可以进行通信,这样它们之间可以进行数据拷贝。

CUDA跟GPU硬件关系

LLM推理

意义:推理框架可以让我们以小的算力成本获得更快的加速效果 目的:高吞吐,低延迟 框架:vLLM是一个开源的大模型推理加速框架,可以通过PagedAttention可以更有效地管理attention计算过程中缓存的张量

Continuous Batching

痛点:每一个批次都是同时计算,同时结束,显存的资源同时释放,导致短的问题过早结束也要等待同一个批次的全部结束才释放资源 问题:一个batch中的不同推理请求的完成步骤可能差异很大,正常情况下已经完成答案生成的请求要等待所有请求都完成后才释放显存,导致GPU未被充分利用 解决:一旦一个批次中的某个句子,已完成得到结果,就会得到一个end标记,这时系统推理框架就运行end后面插入新的句子生成新的token

KV_Cache

为了解决Decoding阶段只能串行以及计算量不断增大的困难 背景:推理时的每个step,都需要用到之前step的所有token,为避免重复计算,我们考虑每个step缓存当前计算的key/value结果,这样之后的step便可直接读取缓存结果而避免重复性的计算 意义:通过空间换时间的思想,提高推理性能

PageAttention

介绍:PagedAttention是vLLM的核心技术,它解决了LLM服务中内存的瓶颈问题。传统的注意力算法在自回归解码过程中,需要将所有输入Tokent的注意力键和值张量存储在GPU内存中,以生成下一个Token。这些缓存的键和值张量通常被称为KV缓存 痛点:显存的内存是随机动态分配的,随着你的计算推进,内存的碎片化会非常严重 解决:参考计算机操作系统的内存管理(虚拟内存和分页思想),允许在不连续的空间里面存储连续的KV的缓存张量(对KV缓存切为大小固定的块,切完的块看为虚拟内存的页,token类比为字节,序列类比为进程),只需要在中间维护一块逻辑和物理内存对应的映射表 优势:(1)提升显存的利用效率;(2)高效的内存共享,例如一个batch种多个样本都是同样一个prompt输入,则并行采样时便可以共享prompt的KV_Cache

LLM

角色约定,few-shot示例、分步引导、输出格式、拒答边界、风格约束、输出格式

  1. 大模型本质是一个对上下文非常敏感的概率生成系统,所以提示词本质是塑造一个局部的概率空间,prompt只擅长澄清任务的目标、约束和激发模型能力,但不擅长缺失知识,动态信息和长链路状态变化
  2. Prompt工程解决大模型无引导乱说话的问题,上下文工程解决上下文组装的问题,以全局规划为核心,对任务做拆解与全流程管控的能力形成了编排层
  3. SDD(Harness的落地依旧):生成约束——》明确需求——》定制计划——》拆解任务——》开始实现
  4. Harness Engineering让程序员从写代码变成了写RuleSkill
  5. 总结:提示词工程让LLM明白你的需求和输出标准,上下文工程给LLM注入精准有效的上下文,驾驭工程可以让LLM持续按规范执行任务并最终交付

其他

并行和并发

并行:能同时执行多个任务 并发:能同时处理多个任务的功能,但不一定是同时