动手点关注
干货不迷路
本文旨在让无大模型开发背景的工程师或者技术爱好者无痛理解大语言模型应用开发的理论和主流工具,因此会先从与LLM应用开发相关的基础概念谈起,并不刻意追求极致的严谨和完备,而是从直觉和本质入手,结合笔者调研整理及消化理解,帮助大家能够更容易的理解LLM技术全貌,大家可以基于本文衍生展开,结合自己感兴趣的领域深入研究。若有不准确或者错误的地方也希望大家能够留言指正。
本文体系完整,内容丰富,由于内容比较多,分多次连载 。
第一部分 基础概念
1.机器学习场景类别
2.机器学习类型(LLM相关)
3.深度学习的兴起
4.基础模型
第二部分 应用挑战
1.问题定义与基本思路
2.基本流程与相关技术
1)Tokenization与Embbeding
2)向量数据库
3)fi netune( 微调 )
4)模型部署与推理
5)prompt
6)编排与集成
7)预训练
第三部分 场景案例
常用参考
2.基本流程与相关技术
4)模型部署与推理
模型适配优化
衡量一个服务是否可以满足生产级使用需要,一般从以下几个方面入手:
1)资源占用合理,首先要能够在有限资源(计算和存储)的设备中部署起来,这里根据场景的不同,包含普通的数据中心服务器或者个人PC设备(GPU环境或者非GPU环境),再或者边缘设备,如手机等。这里的资源占用既包含静态的模型大小,也包含运行时的内存/显存占用大小。
2)达到预期的性能指标,包含吞吐量和延迟。大模型推理服务需要基于场景在吞吐量和延迟上的要求,做模型和代码层面的优化,这包含设备,模型,以及应用,从底到上的多层优化。
3)可扩展,高可用,低成本,能够基于场景规模的不断扩大,可通过加资源的方式水平扩展。在架构上,通过冗余和故障转移等手段提升可用性,通过虚拟化,资源调度等手段提升资源利用率降低成本。
其中,第一,二侧重于模型和代码本身优化,属于白盒优化,第三部分侧重运维和架构,属于黑盒优化。
GPU的面面观
做深度学习,绕不开的就是GPU,那么GPU是什么,在模型训练和推理中到底起什么作用,应该选择什么样的GPU,这些问题我们一一探讨。
GPU与显卡
显卡
GPU,显卡上的处理芯片
GPU(Graphics Processing Unit)是一种专门用于处理图形和图像的专用处理器,它可以大大提高图形计算性能,从而为用户提供更流畅的图形体验。显卡(VedioCard)是一种由GPU和其他专用集成电路构成的计算机扩展卡,使用显卡,可以使电脑在显示图形和图像时更加流畅。因此,GPU是处理图形和图像的专用处理器,而显卡则是将GPU与其他集成电路集成在一起的计算机扩展卡。GPU其核心地位,导致我们往往用GPU型号,如A100,RTX3090 来指代搭载该型号GPU的显卡。
CPU已经足够快了为什么还需要GPU?
这个问题要从CPU和CPU的结构特点和使用场景来分析,CPU是计算机的核心部件之一,其主要功能是执行计算机指令,控制计算机的运行和处理数据。 面向低延时设计的 ,由运算器(ALU,Arithmetic and Logic Unit 算术逻辑 单元)和控制器(CU,Control Unit),以及若干个寄存器和高速缓冲存储器组成,功能模块较多,有 70% 的晶体管用来构建 Cache 和一部分控制单元,计算单元相对少,擅长逻辑控制,串行运算。
随着近年来CPU的计算核心,计算频率,功耗都得到了很大的发展。从能力上讲可以算做是一个多才多艺,干活效率超高的“大学生”。但是对于一些并行计算密集的场景,CPU受限于自己的通用处理器定位,需要完成泛化,多样的指令,其核心数无法大幅度提高,一般也在几十一百左右,并行度受限,即使计算频率很高,其最终速度也比较慢。
而GPU结构比较简单, 面向高吞吐设计 ,专注大规模并行计算和图形数据流处理,能力单一,拥有大量的并行处理单元,每个处理单元可以同时执行指令。如NVIDIA的Turing架构具有数千个并行处理单元,也称为CUDA核心,也叫流处理器(Streaming Processor ,SP),多个SP构成一个Warp(不同代次有差别),而若干Warp加上一些资源(存储资源,共享内存,寄储器)组成一个组成一个基本控制指令单元,流多处理器(Streaming Multiprocessor,SM),拥有独立的指令调度电路,一个SM下所有的SP共享同一组控制指令。一个GPU中包含大量的SM,每个SM又包含大量的SP。
而GPU在执行指令时,每个计算单元就像是成千上万小学生一样,能够同时进行简单工作,具有很高的任务吞吐能力。可以看 出,GPU比CPU的快胜在人海战术,并行化,它的强项在一些需要进行大量无脑并行计算的领域。
@直观理解GPU与CPU工作原理
游戏场景涉及到大量的画面渲染,这类计算的 特点是计算同质化,计算量大,但计算逻辑简单,比如实时渲染环境的明暗变化就是在原有画面基础上进行亮度的调节。CPU只能从上到下顺序调整每个像素点的色阶,而GPU可以并行的对画面进行处理,其数独差异自然天壤之别。
@Nvidia
因此,CPU在某些计算密集型场景并不快,需要有专门的处理器来配合,GPU就是基于这一背景而产生,两者是协同关系,CPU可以将密集型计算交给GPU来处理。CPU负责处理串行任务和控制流,而GPU则专注于大规模的并行计算。
GPU与深度学习
在第一部分中,我们提到了大模型采用的是Transformer这样的深度神经网络架构,而深度学习有一个特点,就是它拥有大量的向量数据输入,以及多层的神经网络层,每一层都含有海量参数,因而,不论是前向计算还是反向传播阶段,每一层都会涉及到大量的矩阵计算(后续将在模型资源占用和计算量计算小节具体分析)。
以Transformer模型BERT、GPT 3.5为例,矩阵乘法的运行时长约占其总运行时长的45-60%。那么加速深度学习性能的核心入手点就是加速矩阵计算的速度。前面提到了CPU并不适合做大规模的并行计算,它面向低延时设计,提升模型训练和推理速度除了死磕CPU和算法外,寻找一个能够支持大规模并行计算的设备就是一个新思路。
在寻找大规模并行计算设备的路上,GPU并不是唯一选择,它不仅需要和DSP,FPGA这样的通用计算芯片竞争,还需要和面向AI设计的TPU,NPU等AI定制芯片(ASIC)竞争。那么,它拥有什么样的优势,使得它牢牢占据在深度学习加速领域的霸主地位。
其优势归结于两个方面,一个是器件本身的场景匹配度,另一个就是软件配套使用的复杂度及通用性。
对于DSP,专门面向数字信号处理而设计, 功耗敏感、计算位宽对DSP很重要, 定点、浮点, 半精度、单精度、双精度, 16位、24位、32位、40 位等各种数据格式规范, 在寻址上, DSP对于数据对齐方式也最灵活, 设置了大量专门的指令对数据进行对齐操作 。因此, 能够高效地 执行数据信号处理,使用场景更多是移动等嵌入式计算设备。
对于FPGA,目前是GPU的劲敌(Intel押注),市面上也有基于CPU+FPGA的机器学习方案,FPGA作为一种高性能、低功耗的可编程芯片,可以根据客户定制来做针对性的算法设计,重新编程就可以执行不同类型的任务,并且FPGA通常比GPU功耗更低,只在需要时才执行特定的任务,并且可以根据需要重新配置,因此,适应用于需要高度定制化、低功耗和低延迟的应用,但与此同时,它采用Verilog/VHDL等底层硬件描述语言实现,需要开发者对FPGA的芯片特性有较为深入的了解,有比较高的编程门槛。在性能上, FPGA 在浮点运算中效率相当低,因为浮点单元必须从逻辑块组装,并且需要大量的资源,这对于深度学习需要大量浮点计算的场景来说是一个比较明显的短板。在成本上,量产成本高,存在单个芯片的编译成本,限制其无法大量生产,更适合用于细分、快速变化的垂直行业,在应用面上较为狭窄。
对于TPU,NPU等定制型AI芯片,针对于神经网络,深度学习做了深度优化,甚至是特定的算法,如一些自动驾驶芯片,量产成本低,但是缺点也比较明显,使用门槛比较高,且研发造价昂贵,需要保证量产才能降低成本,并且通用性差,一旦成型就无法更改,场景和算法受限。
最后,来说说GPU,得益于其专门的设计,天生具备大吞吐量和并行计算 能力,并且它并不止步于现状,紧跟AI需要,结合机器学习特点,更是设计了更专门的处理核心,称为张量核(Tensor cores),可实现混合精度计算,并能根据精度的降低动态调整算力,在保持准确性的同时提高吞吐量,故而在执行张量/矩阵计算 时,它们更快更有效。再加上其天生结构相对简单,其计算核和RAM也相对容易扩展,最终表现就是算力不断提升。 而GPU胜出的另一个核心因素就是编程门槛问题,甚至可以说是关键,因为一旦用户掌握,这就是难以撼动的用户黏性 。这里不得不介绍一下CUDA(注意CUDA是英伟达特有的,后面分解)。 通过它,英伟达不断拓展疆土,超越英特尔、AMD、三星、台积电,成为全球市值最高的半导体公司。目前英伟达的开发者超400万,在过去15年里CUDA的下载量是3000万次,而去年一年,其下载量达到了700万次,英伟达黄仁勋甚至说他们公司是一家软件公司,可见其软件在英伟达的地位 。
Cuda编程
GPU 编程早期被称为通用GPU编程(General-popuse GPU programing,GPGPU),这一时期的程序员借助 Direct3D 和 OpenGL 的图形 API 通过迷惑图形硬件来执行非图形的计算任务。
GPU计算应用。CUDA被设计为支持各种语言和应用编程接口
直到2006年11月,NVIDIA推出了CUDA,CUDA是一种操作GPU计算的硬件和软件架构,它将GPU视作一个数据并行计算设备,而且无需把这些计算映射到图形API,其作为通用的并行计算平台和编程模型,利用NVIDIA GPU中的并行计算引擎,以比CPU更有效的方式解决许多复杂的计算问题。CUDA带有一个软件环境,允许开发人员使用C++作为高级编程语言。如图上图所示,还支持其他语言、应用编程接口或基于指令的方法,如Python、JAVA、OpenACC等。
它的核心是三个关键的抽象(线程组的层次结构、共享内存和屏障同步),将其作为一组最小的语言扩展简单地暴露给程序员,对上层程序员透明,屏蔽了底层的复杂度,大大简化了并行编程的复杂度。根据摩尔定律GPU的晶体管数量不断增多,硬件结构必然是不断的在发展变化,没有必要每次都为不同的硬件结构重新编码,而CUDA就是提供了一种可扩展的编程模型,使得已经写好的CUDA代码可以在任意数量核心的GPU上运行。如下图所示,只有运行时,系统才知道物理处理器的数量。
自动扩展
另一方面,从编程角度来讲,上层开发者想要使用gpu计算到底有多简单,可以参考下面两个pytorch使用GPU的例子:
1)矩阵乘法:
# 使用gpu
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
a = torch.rand((10000,200),device = device) #可以指定在GPU上创建张量
b = torch.rand((200,10000)) #也可以在CPU上创建张量后移动到GPU上
b = b.to(device) #或者 b = b.cuda() if torch.cuda.is_available() else b
c = torch.matmul(a,b)
2)神经网络经典的线性计算:
import torch
in_row,in_f,out_f = 2,2,3
#CPU计算
tensor = torch.randn(in_row,in_f)
l_trans = torch.nn.Linear(in_f,out_f)
l_trans(tensor)
#GPU计算
tensor = torch.randn(in_row, in_f).cuda()
l_trans = torch.nn.Linear(in_f, out_f).cuda()
l_trans(tensor)
经过上面的分析,我们能够理解为什么GPU如此重要以及为什么在深度学习中选择了GPU。那么,它的出现给深度学习带来了什么样的改变呢?
近十年以来,深度学习蓬勃发展,模型精度越来越高,但模型也是越做越大,支撑起它的是不断增强的GPU算力,两者相辅相成。
大模型之所以能够训练出来,不断提升的GPU运算速度是其中关键
大模型代表OpenAI的GPT-3.5有1750亿个参数,据估算,即使单个机器的显存能装得下,用 8 张 V100 的显卡(一台 DGX-1 的配置),训练时长预计 要 36 年;用 512 张 V100 ,训练也需要将近 7 个月;使用 1024 张 80GB A100(6912 CUDA核心和432张量核心), 那么完整训练 GPT-3 的时长可以缩减到 1 个月,而使用 3584个最新GPU H100(目前最强,18432个CUDA核心、576个Tensor核心) 能在短短11分钟内就能完成。通过这个数据不难看出,GPU的强大与否,对于深度学习尤为重要,或者甚至十分关键,而另一面,以A100价格为例,国内售价达到了10万元以上,H100更是高达25万元(还买不到),再加上GPU的高能耗,训练一个模型费用是非常高昂的,这也是我们在这一节介绍大模型真实投入生产,不能简单追求快,还要考虑成本因素的原因。
在下一篇中将继续介绍GPU相关内容,包含GPU品牌和产品型号,性能参数等内容,让你成为GPU专家 ,敬请关注。 。 。
合集目录:
3)微调
4)模型部署与推理
一文探秘LLM应用开发(8)-模型部署与推理(DEMO验证)
