├── 02-大模型推理系统 ├── 05-大模型推理优化(二).md ├── 03-大模型推理与应用.md ├── 04-大模型推理优化(一).md ├── 01-大模型基础知识.md └── 02-大模型结构.md ├── 03-并行编程 ├── 03-Triton-九齿 │ ├── 05-基于九齿的算子开发.md │ ├── 04-九齿与面向张量的元编程.md │ ├── 02-基于-Triton-的算子开发.md │ ├── 03-基于-Triton-的大模型推理.md │ └── 01-Triton-简介与并行编程基础.md ├── 02-OpenCL │ ├── 03-OpenCL-C-算子开发及优化(一).md │ ├── 04-OpenCL-C-算子开发及优化(二).md │ ├── 05-OpenCL-C-算子开发及优化(三).md │ ├── 01-OpenCL-概述及运行时.md │ └── 02-OpenCL-C-编程抽象.md └── 01-CUDA │ ├── 03-CUDA-优化-MatMul.md │ ├── 04-CUDA-优化-Softmax.md │ ├── 05-算子测试框架搭建.md │ ├── 02-CUDA-入门编程.md │ └── 01-并行计算基础知识和应用场景.md ├── CONTRIBUTING.md ├── README.md └── 01-AI 编译器 ├── 03-AI-编译器里的图级别优化.md ├── 05-InfiniTensor-建设情况和-profiling-工具使用实践.md ├── 01-编译器概述.md ├── 04-AI-编译器里的非图级别优化.md └── 02-AI-编译器对-AI-程序的抽象.md /02-大模型推理系统/05-大模型推理优化(二).md: -------------------------------------------------------------------------------- 1 | # 大模型推理优化(二) 2 | -------------------------------------------------------------------------------- /03-并行编程/03-Triton-九齿/05-基于九齿的算子开发.md: -------------------------------------------------------------------------------- 1 | # 基于九齿的算子开发 2 | -------------------------------------------------------------------------------- /03-并行编程/03-Triton-九齿/04-九齿与面向张量的元编程.md: -------------------------------------------------------------------------------- 1 | # 九齿与面向张量的元编程 2 | -------------------------------------------------------------------------------- /03-并行编程/03-Triton-九齿/02-基于-Triton-的算子开发.md: -------------------------------------------------------------------------------- 1 | # 基于 Triton 的算子开发 2 | -------------------------------------------------------------------------------- /03-并行编程/03-Triton-九齿/03-基于-Triton-的大模型推理.md: -------------------------------------------------------------------------------- 1 | # 基于 Triton 的大模型推理 2 | -------------------------------------------------------------------------------- /03-并行编程/02-OpenCL/03-OpenCL-C-算子开发及优化(一).md: -------------------------------------------------------------------------------- 1 | # OpenCL C 算子开发及优化(一) 2 | -------------------------------------------------------------------------------- /03-并行编程/02-OpenCL/04-OpenCL-C-算子开发及优化(二).md: -------------------------------------------------------------------------------- 1 | # OpenCL C 算子开发及优化(二) 2 | -------------------------------------------------------------------------------- /03-并行编程/02-OpenCL/05-OpenCL-C-算子开发及优化(三).md: -------------------------------------------------------------------------------- 1 | # OpenCL C 算子开发及优化(三) 2 | -------------------------------------------------------------------------------- /03-并行编程/01-CUDA/03-CUDA-优化-MatMul.md: -------------------------------------------------------------------------------- 1 | # CUDA 优化 MatMul 2 | 3 | 1. 基础版本的矩阵乘法; 4 | 2. 共享内存分块; 5 | 3. 寄存器分块; 6 | 4. 重排索引; 7 | 5. float4 访存; 8 | 6. 解决 bank conflict; 9 | 7. 内积转外积; 10 | 8. 双缓冲; 11 | 9. 循环展开; 12 | 10. cublas 实现; 13 | 11. tensor core 实现矩阵乘法; 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 讲义命名与格式规范指南 2 | 3 | > 推荐使用 [VS Code](https://code.visualstudio.com/) + [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint) 编辑讲义文档 4 | 5 | - 使用 Markdown(\*.md)或 Typst(\*.typ)编写讲义,文件命名为 `{课程序号:02}-{课程名}.{扩展名}`,课程名中空格和文件名不支持的字符全部替换为 `-`; 6 | - 文本正文一级标题为课程名,应与文件名中的一致; 7 | - 插入讲义的图片与讲义文本放入同级目录,命名为 `{课程序号:02}-{图片序号:02}-{图片主题}.{扩展名}`,图片主题可以不写; 8 | -------------------------------------------------------------------------------- /03-并行编程/01-CUDA/04-CUDA-优化-Softmax.md: -------------------------------------------------------------------------------- 1 | # CUDA 优化 Softmax 2 | 3 | ## 一维 softmax 4 | 5 | - 为了避免数值溢出,每个元素需要减去该向量最大值; 6 | - softmax 的核心在于两次 reduce 操作; 7 | 8 | --- 9 | 10 | > - 先做 max 规约再做 sum 规约,然后做指数变换,这种做法造成两次重复读取数据; 11 | > - 同时做 max 和 sum 规约可以提高访存效率; 12 | 13 | ## 高维向量 softmax 14 | 15 | 1. 操作维度 axis 和其他维度把数据重排为一个二维矩阵,变换过程可视为针对二维矩阵的每一行做 softmax; 16 | 2. blockReduce 的核心在于每个线程块处理一行数据; 17 | 3. warpReduce 的核心在于线程块内每个 warp 处理一行数据; 18 | 4. cudnn库 函数只能针对固定场景做 softmax,应用范围极其有限; 19 | -------------------------------------------------------------------------------- /03-并行编程/01-CUDA/05-算子测试框架搭建.md: -------------------------------------------------------------------------------- 1 | # 算子测试框架搭建 2 | 3 | ## pytorch 库函数的实现逻辑 4 | 5 | - 用户在 python 端调用库函数(torch.softmax); 6 | - pytorch 内部编写一个底层核函数(softmaxKernel),并且提前编译为动态库; 7 | - pytorch 根据用户这边的指令寻找动态库调用底层核函数; 8 | 9 | ## pybind11的使用 10 | 11 | 1. softmax.cu 文件需要添加一个接口来接受 python 端的 numpy 或者 tensor; 12 | 2. setup.py 需要针对 `.cu` 文件进行编译得到动态库; 13 | 3. test_softmax.py 需要调用动态库对 kernel 进行性能和精度测试; 14 | 15 | ## CMake 的使用 16 | 17 | - CMake 可以使用正则表达式来索引全部源文件; 18 | - CMake 可以使用开关来控制不同平台的编译测试; 19 | - CMake 的编译速度更具有优势; 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 人工智能系统训练营(2024 冬季)讲义 2 | 3 | ![GitHub repo size](https://img.shields.io/github/repo-size/LearningInfiniTensor/handout) 4 | [![GitHub Issues](https://img.shields.io/github/issues/LearningInfiniTensor/handout)](https://github.com/LearningInfiniTensor/handout/issues) 5 | [![GitHub Pull Requests](https://img.shields.io/github/issues-pr/LearningInfiniTensor/handout)](https://github.com/LearningInfiniTensor/handout/pulls) 6 | ![GitHub contributors](https://img.shields.io/github/contributors/LearningInfiniTensor/handout) 7 | ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/LearningInfiniTensor/handout) 8 | -------------------------------------------------------------------------------- /01-AI 编译器/03-AI-编译器里的图级别优化.md: -------------------------------------------------------------------------------- 1 | # AI 编译器里的图级别优化 2 | 3 | ## 推理引擎架构 4 | 5 | - Parser: 将代码解析成计算图; 6 | - Graph: 计算图的表示; 7 | - Runtime: 运行时图的表示; 8 | - Backend: 图的后端,将计算图编译成目标代码; 9 | 10 | ## 图优化定义 11 | 12 | 将一种计算图结构,在算术结果不改变的情况下,基于一系列预先写好的模板,对计算图进行相应的图替换操作。 13 | 14 | ## 图优化解决的问题 15 | 16 | - 结构冗余; 17 | - 读写冗余; 18 | 19 | ## 图优化方法 20 | 21 | - 常量折叠; 22 | - 冗余节点消除; 23 | - 计算图替换; 24 | - 算子融合; 25 | - 数据布局转换; 26 | - 自动图优化搜索; 27 | 28 | ## 图优化流程 29 | 30 | 1. 启动时会构建一个图优化 Pass 名字和功能代码映射的表; 31 | 2. 计算图构建完成后在下沉到运行时图之前,会将仓库中的图优化 Pass 中执行一遍; 32 | 3. 如果满足特定的图转换机制会跳转到对应的代码中完成图替换; 33 | 4. 重复步骤 3 直到仓库中的图优化 Pass 没有可以执行的 Pass; 34 | 5. 输出得到新的计算图并下沉到运行时图; 35 | -------------------------------------------------------------------------------- /03-并行编程/01-CUDA/02-CUDA-入门编程.md: -------------------------------------------------------------------------------- 1 | # CUDA 入门编程 2 | 3 | ## CPU 和 GPU的对比 4 | 5 | - CPU 控制单元强大,缓存大,ALU 少; 6 | - GPU 控制单元简单,缓存小,ALU 多; 7 | 8 | --- 9 | 10 | > - 异构计算:将应用程序的计算密集型部分卸载到 GPU 来提供更高的性能,而其余代码仍然在 CPU 上运行; 11 | 12 | ## CUDA 编程重要概念 13 | 14 | 1. 关键字 `__global__`; 15 | 2. 线程网格 grid_dim 和block_dim; 16 | 3. 核函数调用 `<<<...,...>>>`; 17 | 4. 全局同步 `cudaDeviceSynchronize()`; 18 | 5. 线程内同步 `__syncthreads()`; 19 | 20 | ## 异构编程模型 21 | 22 | 1. CPU 端准备数据; 23 | 2. 数据迁移到 GPU; 24 | 3. GPU 端执行计算过程; 25 | 4. 计算结果拷贝回 CPU; 26 | 5. 释放内存; 27 | 28 | ## CUDA 内存模型 29 | 30 | - 寄存器内存(register); 31 | - 共享内存(share memory); 32 | - 全局内存(global memory); 33 | 34 | ## 规约策略 35 | 36 | - 交叉规约; 37 | - 交错规约; 38 | - shuffle warp 规约; 39 | - blockReduce 规约; 40 | -------------------------------------------------------------------------------- /02-大模型推理系统/03-大模型推理与应用.md: -------------------------------------------------------------------------------- 1 | # 大模型推理与应用 2 | 3 | ## 常见大模型文件格式 4 | 5 | - 纯二进制文件(如 .pb/.pt/.ckpt 等); 6 | - safetensors 格式; 7 | - gguf 格式; 8 | 9 | ## 文本生成(Causal LM) 10 | 11 | 对于每个输入 token,模型输出下一个 token 的概率分布。 12 | 13 | ## 采样 14 | 15 | ### Argmax 16 | 17 | 选取概率最大的词,结果单一,常用于精度测试。 18 | 19 | ### 随机采样 20 | 21 | 按照概率分布随机选取词,结果多样性高 22 | 23 | - top-k:从概率最高的 k 个词里采样; 24 | - top-p:从概率累加达到 p 的词里采样; 25 | - temperature:调整概率分布的平滑度,越大采样结果越随机; 26 | 27 | 参数加载时要注意矩阵转置。 28 | 29 | ### Beam Search 30 | 31 | 多次采样,保留概率最高的k个候选结果,然后继续采样,直到达到最大长度或遇到结束符。 32 | 33 | 可以考虑更多未来的 token,效果更好但会占用资源。 34 | 35 | ## KV Cache 36 | 37 | 在多轮推理中,通过缓存前面轮次的 KV 结果,减少重复计算。 38 | 39 | - KV Cache即是大模型的“记忆”; 40 | - 有长度限制; 41 | 42 | ## AI对话 43 | 44 | 通过在文本生成任务中增加角色信息,实现AI对话。 45 | 46 | - Template:模型的对话模板,根据角色对输入增加相应 token; 47 | - 对话回滚:通过回溯 KV Cache,实现对话的重新推理; 48 | -------------------------------------------------------------------------------- /02-大模型推理系统/04-大模型推理优化(一).md: -------------------------------------------------------------------------------- 1 | # 大模型推理优化(一) 2 | 3 | ## AI对话服务的基本功能 4 | 5 | 1. 创建/切换/删除会话 6 | 2. 推理/中断推理 7 | 3. 修改历史对话重推理 8 | 4. 切换历史对话 9 | 10 | ## 服务多用户 11 | 12 | ### 静态批次的局限 13 | 14 | - 对长度不同的输入进行padding会导致计算浪费 15 | - 推理长度不同的请求造成额外的等待 16 | - 不方便随时取消请求 17 | 18 | ### 连续批次(Orca) 19 | 20 | - 以单轮推理为单位将请求池中的多个请求(可以长度不同)组成批次 21 | - 可以批量计算的算子(如QKV计算)同时进行计算,不能批量计算的算子(如attention)每个请求单独进行计算 22 | 23 | ## 混合精度优化 24 | 25 | 模型的参数或计算使用更低精度的数据类型,从而达到减少内存使用或加速计算的目的。 26 | 27 | ### 大模型推理常见数据浮点数类型 28 | 29 | - FP16:大小是FP32的一半,范围和精度都比FP32更低 30 | - BF16:大小是FP32的一半,范围和FP32相同,但是精度比FP16更低 31 | - TF32:大小和范围与FP32相同,精度和FP16相同,需要TensorCore支持 32 | 33 | ### 量化 34 | 35 | - 将模型参数进一步压缩为更小的整数类型,如INT8 36 | - 常用于手机之类内存有限的端侧设备 37 | - 量化方法很多,主要目的是降低内存占用,不一定能提升计算速度 38 | 39 | ## 模型结构优化 40 | 41 | ### MAQ和GQA 42 | 43 | 多组Q对应一组KV,从而减少KV的大小 44 | 45 | ### 混合专家(MoE)模型 46 | 47 | 将MLP层替换为专家网络,推理时只激活部分专家 48 | -------------------------------------------------------------------------------- /01-AI 编译器/05-InfiniTensor-建设情况和-profiling-工具使用实践.md: -------------------------------------------------------------------------------- 1 | # InfiniTensor 建设情况和 profiling 工具使用实践 2 | 3 | ## InfiniTensor 整体建设 4 | 5 | 使用 c++ 开发的AI编译器项目,接受加载 ONNX 表示的模型执行推理,支持多种硬件加速,整体分为图层、算子层和运行时层。 6 | 7 | ### mlir 接入 8 | 9 | 开发仓库及分支:[https://github.com/bitzyz/Infini-mlir](https://github.com/bitzyz/Infini-mlir) 10 | 11 | 目前 mlir 作为 InfiniTensor 前端的一部分存在,其中完成了将 InfiniTensor 已支持的 onnx 格式的 resnet 模型导入为 mlir 格式的工作,并进行了形状推导和一部分的图优化功能。 12 | 13 | ### 统一算子库接入 14 | 15 | 算子库仓库及分支:https://github.com/PanZezhong1725/operators/tree/dev 16 | 17 | 统一算子库定义了一套算子的接口和使用流程,将硬件相关的信息在内部进行了封装使得用户无需考虑硬件算子库使用上的差异,而只需要关注统一算子库的通用接口即可。通过引入统一算子库,对 InfiniTensor 的算子层进行重构,InfiniTensor 重构分支名为 refactor_kernels。 18 | 19 | ## 性能分析实践 20 | 21 | 算子级性能分析:通常只执行单算子的计算,主要目的是判断算子的实现是否足够优,以及发现可能存在的优化空间(常用工具如 NVIDIA Nsight Compute)。 22 | 23 | 端到端性能分析:使用框架推理模型,并且对整体推理过程进行 profile,目的是为了发现框架存在的优化点,优化模型推理的整体性能。(常用工具如 NVIDIA Nsight Sytems)。 24 | -------------------------------------------------------------------------------- /01-AI 编译器/01-编译器概述.md: -------------------------------------------------------------------------------- 1 | # AI 编译器概述 2 | 3 | ## 什么是 AI 编译器 4 | 5 | AI 编译器的主要作用是优化深度学习应用中的张量计算,将其高效部署到人工智能芯片上,以提升模型的执行性能。 6 | 7 | ## 主要优化过程 8 | 9 | ### 图层编译优化 10 | 11 | 分为两大类: 12 | 13 | - 基于专家规则的算子匹配和替换 14 | - 自动图优化 15 | 16 | ### 算子层编译优化 17 | 18 | 分为两大类: 19 | 20 | - 专家手写的算子库 21 | - 算子自动生成框架 22 | 23 | ## 项目概况 24 | 25 | ### InfiniTensor 26 | 27 | InfiniTensor 是开源组织的第一个项目,也是组织名的来源,使用 c++ 开发,接受加载 ONNX 表示的模型实现高效推理,这个项目的结构比较简洁,对初学者来说易于学习和上手。另外,InfiniTensor 还支持多种硬件加速。 28 | 29 | ### RefactorGraph 30 | 31 | RefactorGraph 即“重构图表示”,是继 InfiniTensor 之后的下一代深度学习编译器项目,使用 c++ 开发,顾名思义,它重构了一种通用的计算图表示,这个项目可以单独实现模型的加载和推理,也可以作为前端进行图优化。 32 | 33 | ### TinyInfiniTensor 34 | 35 | 该项目基于团队的开发项目 InfiniTensor,实现了一个简化版本的 AI 编译器。它保留了 InfiniTensor 的计算图和 kernel 层的概念,但去掉了 Python 前端对 ONNX 模型的读取部分,使得项目更加简洁易于上手。作业的测试基于 Google Test (gtest) 框架进行。在初始状态下,所有测试用例均会失败。随着学员们完成相应的作业,这些测试用例将逐渐通过验证。作业的设计围绕着 AI 编译器的关键功能和优化技术点,包括内存分配、算子添加和图优化。 36 | -------------------------------------------------------------------------------- /02-大模型推理系统/01-大模型基础知识.md: -------------------------------------------------------------------------------- 1 | # 大模型基础知识 2 | 3 | ## 大模型 4 | 5 | 大模型:指具有大规模参数和复杂计算结构的机器学习模型。这些模型通常由深度人工神经网络构建而成。 6 | 7 | ### 传统数学模型 8 | 9 | 用已知的数学公式(如多项式),去拟合采样数据;希望寻找到一个能恰好通过这些数据点的参数集合,来完成建模;如果无法找到,就尽量逼近这些数据。有些时候优参数集合可以通过数学的方式直接求解。 10 | 11 | ### 人工神经网络 12 | 13 | 是一种模拟生物神经系统的计算模型。由大量的节点(或称神经元)之间相互联接构成。每个神经元都包含线性计算和非线性计算。线性计算改变了输入信号的权重和偏移,而非线性计算则代表了神经元是否激活。 14 | 15 | - 神经元:线性计算(权重、偏移)和非线性计算的组合。 16 | 17 | - 万能近似定理:三层神经网络(即一个输入层、一个隐藏层和一个输出层)在理论上可以近似任意复杂(有限维度)的决策边界。 18 | 19 | ## 训练与推理 20 | 21 | ### 训练 22 | 23 | - 通过大量已知的数据来调整模型参数,使其能够更准确的对新数据进行预测 24 | 25 | - 定义损失函数,按照减少损失的方向调整参数。(梯度下降法) 26 | 27 | - 模型结构对训练的效果有很大影响 28 | 29 | ### 推理 30 | 31 | - 使用训练好的参数,对新的数据进行预测 32 | 33 | ## 深度神经网络中的算子 34 | 35 | - 矩阵乘法(线性计算):$y=xW^T + b$ 36 | 37 | - 激活函数(非线性计算):常见的激活函数有Sigmoid、ReLU、Tanh、Softmax等 38 | 39 | ### 其他神经网络中的计算结构 40 | 41 | - 深度神经网络通过更多层次的结构,可以用较少的参数捕捉到更为复杂的特征关系,提升参数效率 42 | 43 | - 一些特殊的结构,如:CNN、RNN、Transformer等,可以引导模型用更少的参数捕捉特定的特征 44 | -------------------------------------------------------------------------------- /01-AI 编译器/04-AI-编译器里的非图级别优化.md: -------------------------------------------------------------------------------- 1 | # AI 编译器里的非图级别优化 2 | 3 | ## 内存管理优化 4 | 5 | 优化思路: 6 | 7 | 1. 调整分配/释放的时间点和次数,尽可能减少运行时的分配/释放内存带来的时间开销; 8 | 2. 优化分配过程,尽可能减少总的内存占用。 9 | 10 | 惰性内存分配器(LazyAllocator):在推理开始之前分析整个计算图中 tensor 占用内存的可复用情况,并预分配每个 tensor 的偏移地址,总的内存占用为推理过程的内存峰值。 11 | 12 | ## 与硬件无关的算子优化 13 | 14 | 以 transpose 算子为例,可进行的与硬件无关的优化有: 15 | 16 | 1. 去除形状里大小为 1 的维度; 17 | 2. 合并连续的维度; 18 | 3. 合并末尾连续访存。 19 | 20 | 结论:即使不操作图也不修改 kernel 也能优化性能。 21 | 22 | ## tuning 技术 23 | 24 | 推理框架后端可能会有多种 kernel 实现,例如调用算子库的 kernel、手写的 kernel 和代码生成的 kernel 等。在调用算子进行推理计算时,我们需要选择一个性能最好的 kernel 作为我们实际调用的 kernel,由于每个 kernel 自己可能也有多种实现,所以对于每个 kernel 来说,也需要选择自己最优的算法配置。 25 | 26 | ## 生成和执行任务图 27 | 28 | 使用该技术分为三个不同的阶段:定义(definition),实例化(instantiation)和执行(execution)。 29 | 30 | - 在定义阶段,程序在图中创建各个操作描述以及它们之间的依赖关系。 31 | - 在实例化阶段会记录 graph 中各操作执行的快照,对其进行验证,并执行大部分设置和初始化工作,目的是最大限度地减少启动时需要完成地工作。在这一步生成的实例称为可执行图。 32 | - 可执行图可以在流中被启动,类似于任何其他的 device 侧任务。它可以被启动任意多次,而无需重复实例化。 33 | -------------------------------------------------------------------------------- /03-并行编程/01-CUDA/01-并行计算基础知识和应用场景.md: -------------------------------------------------------------------------------- 1 | # 并行计算基础知识和应用场景 2 | 3 | ## 并行计算特点 4 | 5 | 1. 任务划分为多个子任务; 6 | 2. 并发处理; 7 | 3. 求解速度快; 8 | 9 | --- 10 | 11 | > - 矩阵乘法 C=AB,使用多个处理器分别计算矩阵 C 对应元素; 12 | > - 向量内积 c = A.T@B,使用多个处理器规约计算两两元素之和; 13 | 14 | ## 计算机体系架构 15 | 16 | > - 延迟:发送内存请求,即实际完成数据移动需要的时间; 17 | > - 带宽:单位时间移动数据量,即数据传输的速度; 18 | 19 | - 冯诺伊曼体系架构的特点是:计算存储分离; 20 | - 冯诺伊曼体系架构的性能瓶颈是:IO 设备访问速度远远慢于 CPU 计算速度; 21 | - 冯诺伊曼体系架构的解决方案是:使用多级存储; 22 | 23 | ## 并行计算三大定律 24 | 25 | > - 任务(task):并行计算处理的对象; 26 | > - 工作量(workload):完成任务的全部开销总和; 27 | > - 执行率(execution rate):单个处理器单位时间处理的工作量; 28 | > - 加速比(scalability):固定工作量下单机处理时间 ÷ 多机处理时间; 29 | > - 理想加速比(ideal scalability):处理器增多的比例; 30 | > - 并行效率(parallel effiency):加速比 ÷ 理想加速比; 31 | 32 | ### 阿姆达尔定律(Amdahl’law) 33 | 34 | - 工作量固定的情况下,加速比存在上限,并行效率趋于 0; 35 | 36 | ### 古斯塔法森定律(Gustafson’s Law) 37 | 38 | - 工作量随着处理器缩放从而保持处理时间固定,加速比不存在上限,并行效率不超过 1; 39 | 40 | ### 孙-倪定律(Sun-Ni’s Law) 41 | 42 | - 并行部分工作量可以随着处理器按照比例 G(N) 缩放,加速比不存在上限,并行效率趋于 1; 43 | -------------------------------------------------------------------------------- /03-并行编程/02-OpenCL/01-OpenCL-概述及运行时.md: -------------------------------------------------------------------------------- 1 | # OpenCL 概述及运行时 2 | 3 | ## OpenCL 发展史 4 | 5 | 2008 年由苹果公司提出,并移交给 Khronos Group,以开放规范方式推进。目前最新大版本为 3.0。 6 | 7 | ## OpenCL 概述 8 | 9 | OpenCL,全称为 Open Computing Language 开放计算语言,是一种开放、无版税、适用于跨平台并行编程的异构计算编程模型。 10 | 11 | [规范文档](https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html)可任意使用。 12 | 13 | ## 异构计算架构 14 | 15 | ### 平台 16 | 17 | - 定义:一个主机连接到一个或多个 OpenCL 设备; 18 | - 平台层的必要性来自 OpenCL 的异构通用性; 19 | - CUDA 无对应物; 20 | 21 | ### 设备 22 | 23 | - 定义:指定和查询 OpenCL 设备; 24 | 25 | ### 上下文 26 | 27 | - 定义:设备资源分配和交互的空间; 28 | 29 | ### 存储 30 | 31 | - 异构计算设备通常需要自己的存储器(至少是逻辑上的存储器)以达到较好的性能; 32 | - OpenCL 2.0 新增共享虚拟存储(SVM)抽象; 33 | - 共享虚拟存储的操作除分配外全异步; 34 | 35 | ### 队列 36 | 37 | - 定义:异构计算设备的工作流; 38 | - 主处理器与协处理器的交互通过与任务队列的交互完成,主要操作是排队和同步; 39 | 40 | ### 事件 41 | 42 | - 在不同步的情况下获取队列状态信息; 43 | - 可实现多个任务队列之间的同步; 44 | - 本次训练营用不到; 45 | 46 | ### 核函数 47 | 48 | - 使用 [OpenCL C](https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_C.html) 编程; 49 | - 在主机完成源码编译,并发射(Launch)到任务队列上执行; 50 | -------------------------------------------------------------------------------- /01-AI 编译器/02-AI-编译器对-AI-程序的抽象.md: -------------------------------------------------------------------------------- 1 | # AI 编译器对 AI 程序的抽象 2 | 3 | ## AI 程序的特征 4 | 5 | 1. 基于深度神经网络,强时序性/层序性,控制流少; 6 | 2. 操作大规模数据,以高维数组为基本数据类型; 7 | 3. 完全无副作用,仅使用函数调可表示整个过程; 8 | 9 | --- 10 | 11 | > - 在 AI 程序中,高维数组被称为张量(Tensor); 12 | > - 在 AI 程序中,函数调用被称为算子(Operator); 13 | 14 | ## 计算图 15 | 16 | 由于上述特征,AI 程序可以表示为以算子为节点,以张量为边的有向无环图(DAG)。 17 | 18 | - 计算图本质是由函数调用组成的大型函数调用,因此具有输入输出; 19 | - 计算图是递归的结构,即计算图的任何子图都满足计算图的定义; 20 | - 计算图的输入输出可以视为入度或出度为零的节点,也可以视作没有源或目的的节点; 21 | - 由于节点是算子,算子是函数调用,因此计算图中节点的入边和出边是有序的; 22 | 23 | ## InfiniTensor 和 RefactorGraph 中的计算图实现 24 | 25 | ### InfiniTensor 26 | 27 | 计算图的拓扑隐藏在对象指针指向关系中,操作复杂。 28 | 29 | - 张量([tensor_base.h](https://github.com/InfiniTensor/InfiniTensor/blob/master/include/core/tensor_base.h)/[tensor.h](https://github.com/InfiniTensor/InfiniTensor/blob/master/include/core/tensor.h)); 30 | - 算子([operator.h](https://github.com/InfiniTensor/InfiniTensor/blob/master/include/core/operator.h)); 31 | - 计算图([graph.h](https://github.com/InfiniTensor/InfiniTensor/blob/master/include/core/graph.h)); 32 | 33 | ### RefactorGraph 34 | 35 | 计算图的拓扑和操作逻辑与张量和算子的定义解耦。 36 | 37 | - 图拓扑类型([container.h](https://github.com/InfiniTensor/RefactorGraph/blob/master/src/01graph_topo/include/graph_topo/container.h)); 38 | -------------------------------------------------------------------------------- /03-并行编程/02-OpenCL/02-OpenCL-C-编程抽象.md: -------------------------------------------------------------------------------- 1 | # OpenCL C 编程抽象 2 | 3 | ## 上节课知识回顾 4 | 5 | 1. 平台(Platform) 6 | 2. 设备(Device) 7 | 3. 上下文(Context) 8 | 4. 存储(Memory) 9 | 5. 队列(Queue) 10 | 6. 事件(Event) 11 | 12 | ## 本节课内容 13 | 14 | ### 1 执行模型 15 | 16 | #### 1.1 主机与设备分工 17 | 18 | - **主机端程序**:负责 OpenCL 初始化、内核管理、任务提交与数据传输; 19 | - **设备端内核程序**:运行在设备上的并行计算代码,由 OpenCL C 编写; 20 | 21 | #### 1.2 数据传输 22 | 23 | - **主机到设备**:通过 SVM(共享虚拟内存),直接映射设备内存到主机地址空间,可以避免显式的拷贝操作,提供更高效的内存共享; 24 | - **设备到主机**:SVM 允许主机直接访问设备上的数据,避免了不必要的数据拷贝,提高了性能; 25 | - **优化**: 26 | - 利用局部内存(Local Memory); 27 | - 减少不必要的传输操作; 28 | 29 | #### 1.3 NDRange 30 | 31 | - OpenCL 通过 NDRange(索引空间)管理工作项; 32 | - **全局范围**:所有工作项总数; 33 | - **局部范围**:工作组大小; 34 | - **偏移量**:索引起点; 35 | 36 | #### 1.4 工作项与工作组 37 | 38 | - **工作项(Work-item)**:最小执行单元; 39 | - **工作组(Work-group)**:工作项的集合; 40 | - **全局 ID 和 局部 ID** 41 | - **公式**:`全局 ID = 工作组 ID × 工作组大小 + 局部 ID`; 42 | 43 | ### 2 编程模型 44 | 45 | #### 2.1 数据并行模型 46 | 47 | - 同一逻辑操作处理多个数据元素; 48 | - 映射到 NDRange 并行执行; 49 | - 同步 50 | - **组内同步**:`barrier()` 确保局部数据共享一致性; 51 | - **组间同步**:需由主机端逻辑控制; 52 | 53 | #### 2.2 任务并行模型 54 | 55 | - 各任务在不同工作项中执行不同操作; 56 | - 适用于独立任务; 57 | 58 | ### 3 例:向量加法——从串行到并行的实现 59 | 60 | 为了帮助理解并行编程的概念,我们以向量加法为例,逐步展示如何从串行实现扩展到多线程,并最终利用 OpenCL 实现真正的并行计算。 61 | -------------------------------------------------------------------------------- /02-大模型推理系统/02-大模型结构.md: -------------------------------------------------------------------------------- 1 | # 大模型结构 2 | 3 | ## 传统模型 vs 大语言模型 4 | 5 | - 传统模型:vec2vec,一个输入对应一个输出,即输出长度与输入长度一致; 6 | - 大语言模型:seq2seq,输出与输入都是任意长度的序列,长度不一致; 7 | 8 | ## 从文本到向量输入 9 | 10 | ### 词表生成(BPE算法) 11 | 12 | 1. 初始化:将文本中每个字符当作一个独立的 token; 13 | 2. 统计频率:计算文本中每个字符对的出现频率; 14 | 3. 合并字符对:找到频率最高的字符对,并将其合并为一个新的 token; 15 | 4. 更新词汇表:将新生成的 token 添加到词汇表中,并在文本中替换所有该字符对出现的地方; 16 | 5. 重复步骤 2-4:反复执行上述步骤,直到达到预定的 token 数量或不能再找到新的字符对; 17 | 18 | ### Tokenizer 19 | 20 | 1. Encode:将文本转换为 token 序列; 21 | 2. Decode:将 token 序列转换为文本; 22 | 23 | ### 词嵌入(Embedding) 24 | 25 | #### one-hot 编码 26 | 27 | - 将每个 token 映射到一个词表长度的向量,向量的每一维对应一个 token; 28 | - 缺点:向量维度过大、稀疏,不具备语义信息; 29 | 30 | #### 词向量 31 | 32 | 将词映射到低维空间,使得相似的词具有相似的向量表示。 33 | 34 | ## Llama大模型结构 35 | 36 | ### RMS Normalization 37 | 38 | 为了防止梯度爆炸,对梯度进行标准化。 39 | 40 | $$x_i=\frac{x_i\times g_i}{\sqrt{\frac{1}{n}\sum_{i=1}^n x_i^2+\epsilon}}$$ 41 | 42 | 其中, $g$ 是权重向量, $\epsilon$ 是防止分母为 0 的小值。 43 | 44 | ### MLP 45 | 46 | 使用 Silu 作为激活函数。 47 | 48 | $$Y=(Silu(X·W_{gate}^T)×X·W_{up}^T)·W_{down}^T$$ 49 | 50 | 其中, $W_{gate}$ 、 $W_{up}$ 和 $W_{down}$ 是权重矩阵。 51 | 52 | ### 自注意力机制 53 | 54 | 每个 token 都会通过和权重矩阵 $(W_q, W_k, W_v)$ 相乘得到一组 query 向量 $Q_i$ ,key 向量 $K_i$ ,value 向量 $V_i$ 。 55 | 56 | 每个 token 的 query 都与之前 token 的 key 进行注意力计算,代表之前的某个词与当前词的关联程度(注意力)。 57 | 58 | query 向量和 key 向量会额外计算旋转位置编码(RoPE)增加位置信息。 59 | 60 | $$Attention(Q,K,V)=masked\underline{~}softmax(\frac{QK^T}{\sqrt{d_k}})V$$ 61 | 62 | 最终结果与输出权重矩阵 $W_o$ 相乘得到维度为 hidden_size 的输出向量。 63 | 64 | ### 输出层 65 | 66 | 将输出向量映射到 token 空间,得到一个与词表相同长度的向量,代表下个 token 的概率分布。 67 | 68 | 一些模型的输出嵌入权重与输入嵌入权重共享(tie_word_embeddings)。 69 | -------------------------------------------------------------------------------- /03-并行编程/03-Triton-九齿/01-Triton-简介与并行编程基础.md: -------------------------------------------------------------------------------- 1 | # Triton 简介与并行编程基础 2 | 3 | ## 什么是 [Triton](https://triton-lang.org/)? 4 | 5 | * 一门并行编程语言及其编译器; 6 | * 专注于高效地实现高性能计算内核; 7 | * 编程环境基于 Python。 8 | 9 | ## 串行编程与并行编程 10 | 11 | * 串行:按顺序执行 12 | * 并行:同时执行 13 | 14 | ## 实际上的并行编程更为复杂 15 | 16 | ### 使用 CUDA 时所需要进行的考虑 17 | 18 | * 内存合并(memory coalescing) 19 | 20 | * 共享内存管理(shared memory management) 21 | 22 | * 流式多处理器内部的调度(scheduling within SMs) 23 | 24 | * 流式多处理器之间的调度(scheduling across SMs) 25 | 26 | ### 使用 Triton 时所需要进行的考虑 27 | 28 | * ~~内存合并(memory coalescing)~~ 29 | 30 | * ~~共享内存管理(shared memory management)~~ 31 | 32 | * ~~流式多处理器内部的调度(scheduling within SMs)~~ 33 | 34 | * 流式多处理器之间的调度(scheduling across SMs) 35 | 36 | ## 使用 Triton 实现向量加法 37 | 38 | 请看 Triton 官方网站中的[向量加法](https://triton-lang.org/main/getting-started/tutorials/01-vector-add.html)教程。 39 | 40 | ## Triton 的 Python API 41 | 42 | * [`triton.language.program_id`](https://triton-lang.org/main/python-api/generated/triton.language.program_id.html#triton.language.program_id) 43 | * [`triton.language.arange`](https://triton-lang.org/main/python-api/generated/triton.language.arange.html#triton.language.arange) 44 | * [`triton.language.load`](https://triton-lang.org/main/python-api/generated/triton.language.load.html#triton.language.load) 45 | * [`triton.language.store`](https://triton-lang.org/main/python-api/generated/triton.language.store.html#triton.language.store) 46 | 47 | ## 使用 PyTorch 模拟 `arange` 相关计算 48 | 49 | ```python 50 | >>> import torch 51 | >>> x = torch.arange(4) 52 | >>> x 53 | tensor([0, 1, 2, 3]) 54 | >>> x + 4 55 | tensor([4, 5, 6, 7]) 56 | >>> x + 8 57 | tensor([ 8, 9, 10, 11]) 58 | >>> x + 12 59 | tensor([12, 13, 14, 15]) 60 | ``` 61 | --------------------------------------------------------------------------------