网络架构

网络架构

等轴测视角的架构立交图,其中一条表示流分支为全连接、空间、序列和类注意力路径,随后重新汇合。

目的

为什么选择神经网络架构既是一项建模决策,也是一项基础设施承诺?

选择神经网络架构既是一项建模决策,也是一份与物理规律订立的契约。这项承诺始于数据中的结构。与该结构相匹配的架构可以用更少的参数和样本完成学习,而匹配不佳的架构则需要消耗额外的数据和机器时间,来弥补不合适的计算模式。卷积、注意力、循环和嵌入查找不仅编码了对数据的不同假设,还会形成不同的计算、状态和数据移动模式。这些模式决定了计算能否顺利并行化、中间状态能否容纳于内存,以及在所需规模下训练和模型服务的成本是否仍然可承受。两种架构可能达到相近的预测质量,却具有不同的内存占用和延迟特征,同时为后续效率优化技术提供不同的应用空间。因此,仅凭基准测试准确率,无法判断哪种设计能够持续可行。架构承诺的影响还会扩展到模型之外。数据流水线会采用特定的输入结构,训练基础设施会围绕模型的计算特征进行配置,服务系统会针对其请求路径进行调优,监控也会承接其失效模式。当这些依赖不断累积时,更换架构可能意味着重建周边系统的大部分组件。只有当预测性能的收益始终与完整的部署环境相容时,架构决策才是合理的。用数据—算法—机器的视角来看,架构在根本上就是算法与机器的协同设计:数学计算图决定机器必须执行的工作,而机器资源预算则限定哪些计算图在实践中可行。

学习目标
  • 区分 MLP、CNN、RNN、Transformer 和 DLRM 类推荐模型的计算特征
  • 解释归纳偏置如何利用不同数据类型中的结构
  • 分析不同架构家族的计算复杂度与内存规模增长规律
  • 识别支持深层网络训练的基本构件,如跳跃连接、归一化和门控
  • 应用架构选择框架,使模型设计与数据特征相匹配
  • 评估计算、内存访问和数据移动如何决定硬件映射效率
  • 在延迟、带宽和并行化约束下,审视架构选择中的谬误

架构原则

全连接模型会将参数和内存花费在图像很少需要的关系上。卷积神经网络(CNN)编码了局部性,而多层感知机(MLP)没有。矩阵乘法、激活函数和梯度计算构成了神经网络的“动词”。架构将这些动词组装成计算图:针对特定数据类型和计算约束进行优化的专门结构。在硅契约(原则 原则(英文原版))下,每种架构都与硬件达成了一项隐含协议,以特定的计算模式换取在某些问题类别上的效率。

三种架构的纵向列表,配有由深到浅的圆点:CNN(最深,具有较强的空间先验)、Transformer(中等)、MLP(最浅,无结构先验),按归纳偏置强度排序。

归纳偏置从强(CNN)到弱(MLP):先验越强,所需数据越少。

每种神经网络架构都会决定如何组织计算,以匹配数据的内在结构。图像具有空间局部性,语言具有序列依赖,而表格记录通常没有固定的空间或序列组织形式。架构将关于这些模式的假设直接编码到计算图中,而这些假设会影响参数数量、硬件利用率和部署可行性。因此,架构选择是一个系统工程问题,它直接影响铁律中的两项:运算次数 \(O\) 和数据移动量 \(D_{\text{vol}}\)。每种架构所编码的结构假设称为归纳偏置,1 它也是贯穿本章的统一概念。

Definition 1.1: 归纳偏置

归纳偏置 是内置于模型架构中的一种结构约束,它通过将领域特定假设(如空间局部性或序列顺序)直接编码到计算图中,限制假设空间,从而使模型能够从有限数据中实现泛化。

  1. 意义:归纳偏置可以减少实现泛化所需的数据集规模 \((D)\)。对于一个输出特征检测器,全连接方式使用 \(\mathcal{O}(N_{\text{pix}} C_{\text{in}})\) 个参数,而共享的 CNN 滤波器使用 \(\mathcal{O}(K^2 C_{\text{in}})\) 个参数,并应用于每个位置,耗费 \(\mathcal{O}(N_{\text{pix}} K^2 C_{\text{in}})\) 次运算。因此,对于一幅 \(224{\times}224\) 的 RGB 图像,一个共享的 \(3{\times}3\) 滤波器所用的参数量约为一个全连接特征检测器的 1/5,575.1×,从而减少参数存储量,并且通常也减少了避免过拟合所需的数据量。
  2. 区别:正则化在训练时通过 L1/L2 项惩罚假设的复杂度,而归纳偏置在架构设计阶段就限制了假设空间:与局部模式相比,CNN 对非局部函数的表示更为间接;正则化则通过训练目标抑制复杂度。
  3. 常见误区:一种常见误解是,归纳偏置越强总是越好。较强的局部性偏置(CNN)在空间数据上表现出色,但在表示语言中的长程依赖时,不如全局注意力直接;全局注意力以 \(\mathcal{O}(S^2)\) 的分数计算成本支持长程依赖。

由三个方框纵向堆叠而成的数据—算法—机器结构:数据(灰色,顶部)、算法(橙色,高亮,中部)、机器(灰色,底部)。高亮的算法方框标示架构所在的轴。

架构是数据—算法—机器中的算法轴:它设定运算次数预算。

CNN 编码了空间局部性的归纳偏置:邻近像素比远处像素更重要。Transformer 允许每个元素关注其他任意元素,以二次规模的分数计算成本实现长程关系。这些偏置通过限制架构所能表示的函数空间,帮助架构高效学习。如果缺乏适当的偏置,模型可能需要多得多的数据和计算才能学到相同的结构。在各类偏置的实际应用都得到介绍之后,section 1.10 中的统一框架将这些架构家族整合起来。

机器学习系统面临一个核心工程权衡:表示能力与计算效率。根据机器学习系统铁律(原则 原则(英文原版)),架构选择是运算次数项 \(O\) 的首要决定因素。Transformer 的注意力机制能够实现全局关系,但其运算次数随序列长度 \(S\) 按 \(\mathcal{O}(S^2)\) 增长;CNN 则利用空间局部性,使运算次数随空间位置数量线性增长。为工作负载的数据匹配恰当的归纳偏置,同时设定可控的运算次数预算,这构成了神经网络架构选择的实践。

Example 1.1: Netflix 未上线的集成模型(2009 年)
背景:Netflix 于 2009 年颁发了 $1M 大奖,奖励推荐准确率提升 10% 的方案 (Johnston 2012)。

机制:将获奖方案的性能提升应用于生产环境需要投入大量工程工作,而当时 Netflix 的业务正从邮寄 DVD 转向流媒体。这一转变也带来了更丰富的观看信号,并改变了个性化系统需要优化的目标。

影响:额外的准确率收益不足以抵偿生产落地所需的投入,因此 Netflix 没有部署大奖获奖代码。

应对:Netflix 保留了早期进步奖方案中的两种算法,并将推荐系统工作转向流媒体时代的个性化。

系统启示:只有当集成成本和优化目标仍然与生产系统相匹配时,离线指标的提升才有价值。

Johnston, Casey. 2012. “Netflix Never Used Its $1 Million Algorithm Due to Engineering Costs.” Ars Technica, April.

选择架构骨干,就为下游硬件设定了主要的内存布局和计算模式。Table 1 对比了五大神经网络家族的空间与时间归纳偏置、张量运算和内存访问特征。

Table 1: 神经网络架构家族:每个家族针对一种不同的数据结构,并呈现出不同的系统瓶颈。瓶颈一列可直接从铁律推导出来:MLP 的稠密激活对内存带宽提出较高要求;CNN 在大量像素上复用卷积滤波器,因此对计算吞吐量提出较高要求;RNN 受到阻碍并行化的顺序依赖限制;Transformer 计算二次规模的分数交互,并可能显式存储二次规模的分数;DLRM 则通过嵌入表对 TB 级内存容量提出较高要求。
架构 数据类型 核心创新 系统瓶颈
MLP 表格/无结构 全连接 内存带宽
CNN 空间数据(图像) 局部滤波器 + 权重共享 计算吞吐量
RNN 序列数据(时间序列) 循环状态 顺序依赖
Transformer 关系数据(语言) 动态注意力 二次规模的分数计算;可选的 \(S^2\) 存储
DLRM 类别数据(推荐) 嵌入表 内存容量(TB 以上)

本书中有五种具体模型架构反复作为灯塔模型出现:它们是稳定的参照点,将抽象概念落实到具体的系统现实中。这些示例是 工作负载原型 中介绍的工作负载原型(如计算密集型巨兽和带宽吞噬者)的具体实现。它们的选择反映了模型演进的经验帕累托前沿(figure 1),该图将 ImageNet 准确率与计算成本对应起来。

Figure 1: 效率前沿:ImageNet Top-1 准确率与计算成本(GMACs)的关系。代表性数据点汇编自已发表的 AlexNet、VGG、ResNet、Inception、MobileNetV2、EfficientNet、ViT、Swin Transformer 和 ConvNeXt 模型报告 (Krizhevsky et al. 2012; Simonyan and Zisserman 2015; He et al. 2016a; Szegedy et al. 2015; Sandler et al. 2018; Tan and Le 2019; Dosovitskiy et al. 2021; Liu et al. 2021; Liu et al. 2022)。虚线“帕累托前沿”是一条示意性的权衡曲线,并非重新运行基准测试的结果;具体准确率和报告的计算量会随模型变体、训练方案、实现方式和运算计数约定(乘加运算与浮点运算)而变化。图例区分了六个家族:早期 CNN(灰色)、稠密 CNN(蓝色)、高效移动端架构(绿色)、EfficientNet 类模型(紫色)、现代 CNN(橙色)和 Transformer(红色)。高效架构和现代 CNN 家族引领这一前沿;Transformer 以大量计算换取灵活的长程建模能力,但并未主导该前沿,ViT-B/16 则位于前沿下方。
Simonyan, Karen, and Andrew Zisserman. 2015. “Very Deep Convolutional Networks for Large-Scale Image Recognition.” arXiv Preprint.
Szegedy, Christian, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, and Andrew Rabinovich. 2015. “Going Deeper with Convolutions.” 2015 IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 1–9. https://doi.org/10.1109/cvpr.2015.7298594.
Sandler, Mark, Andrew Howard, Menglong Zhu, Andrey Zhmoginov, and Liang-Chieh Chen. 2018. “MobileNetV2: Inverted Residuals and Linear Bottlenecks.” 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition, 4510–20. https://doi.org/10.1109/cvpr.2018.00474.
Tan, Mingxing, and Quoc V Le. 2019. “EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks.” International Conference on Machine Learning (ICML), 6105–14.
Liu, Ze, Yutong Lin, Yue Cao, Han Hu, Yixuan Wei, Zheng Zhang, Stephen Lin, and Baining Guo. 2021. “Swin Transformer: Hierarchical Vision Transformer Using Shifted Windows.” 2021 IEEE/CVF International Conference on Computer Vision (ICCV), 9992–10002. https://doi.org/10.1109/ICCV48922.2021.00986.
Liu, Zhuang, Hanzi Mao, Chao-Yuan Wu, Christoph Feichtenhofer, Trevor Darrell, and Saining Xie. 2022. “A ConvNet for the 2020s.” 2022 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 11966–76. https://doi.org/10.1109/CVPR52688.2022.01167.

这些模型是理解系统约束的典型工作负载。如 figure 1 所示,每个模型都在准确率与计算成本的权衡中占据独特位置。图中前沿应被理解为代表性架构论文的历史图谱,而非受控条件下的基准测试表。它勾勒出一条演进路径:从优先追求准确率的稠密 CNN,经过降低单位准确率计算量的 MobileNet,再到以大量计算成本换取灵活长程建模能力的 Transformer 架构。设计阶段所作的架构选择,决定了系统在这一前沿上的位置。

灯塔模型名录:模型小传

五个模型之所以承担灯塔角色,是因为它们各自突出呈现了一种反复出现的系统瓶颈:计算(ResNet-50)、内存带宽(GPT-2)、内存容量(DLRM)、边缘端延迟(MobileNetV2),以及关键词检测(KWS)中的持续运行功耗。

ResNet-50 (He et al. 2016a) 是计算密集型视觉灯塔模型的代表。残差网络(ResNet)解决了极深普通网络中的退化问题:即使容量充足,增加层数仍可能提高训练误差。通过引入改善优化过程和梯度流动的“跳跃连接”,它使 50 层、100 层乃至 1000 层的网络成为可能。ResNet 架构赢得了 ImageNet 2015 竞赛(采用极深的 152 层模型),而 ResNet-50 已成为计算机视觉中广泛使用的骨干网络和基准工作负载。从系统角度看,它是一种高度规则、计算密集的工作负载,几乎完全由稠密卷积组成,因此适合用于测试 GPU 的浮点运算吞吐量。

GPT-2 (Radford et al. 2019) 是受带宽限制的语言灯塔模型的代表。生成式预训练 Transformer 2 表明,在海量数据集上扩展简单的纯解码器 Transformer 架构,可以实现连贯的文本生成。BERT 是一种双向读取上下文的编码器式 Transformer,而 GPT-2 按顺序(以自回归方式2)生成文本,由于每个解码步骤都要读取模型权重,因此在批量大小为 1 和小批量解码期间会产生显著的内存带宽压力。它是 Llama 和 ChatGPT 等大语言模型的原型。

DLRM (Naumov et al. 2019) 是稀疏推荐这一灯塔场景的代表。Meta 将 DLRM 开源,以展示一种在关键方面不同于 CNN 和 Transformer 的工作负载。视觉模型和语言模型侧重计算,而推荐系统侧重内存。推荐系统必须在规模可达 TB 级的庞大嵌入表中查找用户和物品偏好,这为延迟敏感的模型服务带来了独特挑战(模型服务)。DLRM 是评估数据中心内存容量和稀疏内存访问模式的实用基准。

Lighthouse 1.1: 典型工作负载
在计算机体系结构中,无互锁流水级微处理器(MIPS) 处理器常用于讲授流水线技术,并非因为它是现有最快的芯片,而是因为它最清晰地体现了精简指令集计算机(RISC)的原则。类似地,本书将 ResNet-50、GPT-2、DLRM、MobileNetV2 和 KWS 用作典型工作负载。研究这些“灯塔”,可以提炼出有关数学运算、内存数据搬移和局部性的工程原理,即使具体模型架构不断演进,这些原理仍然成立。

MobileNet (Howard et al. 2017) 是边缘效率这一灯塔场景的代表。MobileNet 将效率放在首位,挑战了模型规模不断扩大的趋势。它推动了深度可分离卷积在高效视觉模型中的普及;对于 \(3{\times}3\) 卷积核,这一架构创新使 FLOPs 缩减至原来的 1/8–1/9(缩减倍数为 8–9\(\times\)),而准确率损失很小。较小的计算需求使 MobileNet 天然适合 模型压缩 中介绍的压缩和低精度部署技术(以更少的位数存储每个数值并执行计算)。它成为视觉模型与智能手机及嵌入式设备的电池和延迟约束进行协同设计时的参考模型家族。

Warden, Pete. 2018. “Speech Commands: A Dataset for Limited-Vocabulary Speech Recognition.” arXiv Preprint arXiv:1804.03209, ahead of print. https://doi.org/10.48550/arXiv.1804.03209.
Warden, Pete, and Daniel Situnayake. 2020. TinyML: Machine Learning with TensorFlow Lite on Arduino and Ultra-Low-Power Microcontrollers. O’Reilly Media.
Banbury, Colby R, Chuteng Zhou, Igor Fedorov, Ramon Matas, Urmish Thakker, Dibakar Gope, Vijay Janapa Reddi, Matthew Mattina, and Paul N Whatmough. 2021. “MicroNets: Neural Network Architectures for Deploying TinyML Applications on Commodity Microcontrollers.” Proceedings of Machine Learning and Systems 3: 517–32.
Banbury, Colby, Vijay Janapa Reddi, Peter Torelli, Jeremy Holleman, Nat Jeffries, Csaba Kiraly, Pietro Montino, et al. 2021. “MLPerf Tiny Benchmark.” arXiv Preprint.

KWS (Warden 2018) 是持续运行的 TinyML 这一灯塔场景的代表。关键词检测模型(例如检测“Hey Siri”或“Ok Google”的模型)代表了效率要求的极端情形。这些模型通常采用深度可分离 CNN,旨在具有 KB 级内存和毫瓦级功耗预算的“始终开启”微控制器上运行,体现了 TinyML 的约束 (Warden and Situnayake 2020; C. R. Banbury et al. 2021; C. Banbury et al. 2021)。它们迫使工程师精打细算每个字节和每个时钟周期,从而推动极致量化(INT8 和 INT4)以及专用硬件的发展。这些模型简介共同说明了为何灯塔并非模型目录:每个灯塔都凸显一种不同的瓶颈特征,而算术强度分析可以量化这些特征。

工作负载特征:算术强度谱系

ResNet-50 在许多空间位置复用卷积权重,而批大小为 1 的 GPT-2/Llama 解码每次为一个词元流式读取大量权重和 KV 缓存状态。这种对比引出了算术强度,即 神经计算 中建立的 FLOP/byte 比值;将其与硬件的 Roofline 曲线结合,可以评估工作负载更可能受计算限制还是受内存限制。

在对数刻度上纵向排列的三个水平条形,分别标注 ResNet 80、MobileNet 43 和 GPT-2 0.5 FLOP/字节,最上方的条形远长于最下方。

仅考虑权重的近似指标表明,ResNet 的算术强度约为批大小为 1 时 GPT-2 的 160\(\times\)。

这些瓶颈反映了底层数学运算的特性,但此处的计算仅是考虑权重的近似指标,并非对主存流量的完整测量。它将浮点运算量除以 FP32 模型权重的字节数,未计入激活值、中间结果和 KV 缓存的流量。批处理可以在多个样本或词元之间摊薄权重传输开销,而额外的状态搬移则可能降低实际算术强度。计算复杂度速查表 给出了这一近似指标所使用的各类操作的 FLOP 和参数量公式。Table 2 比较了三个灯塔场景,并展示了在这些假设下约 160.2× 的差距。

Table 2: 灯塔工作负载特征:三个模型场景下仅考虑权重的 FP32 算术强度近似指标。这些数值表明不同的计算和带宽压力,但并不决定固定的硬件适配倾向;实际瓶颈取决于执行方式和硬件资源配比。
模型家族 灯塔 算术强度 \((I)\) 硬件适配倾向
稠密 CNN ResNet-50 ~80.1 FLOP/byte 计算资源丰富(GPU/TPU)
高效视觉模型 MobileNetV2 ~42.8 FLOP/byte 均衡型(移动端 NPU)
Transformer GPT-2(推理) ~0.50 FLOP/byte 带宽资源丰富的加速器

此表为架构选择提供了一项系统层面的依据。任务要求决定哪些模型家族可行,而批大小、精度、序列长度、实现方式、缓存行为和目标硬件则决定这一近似指标能否预测部署后的瓶颈。MobileNet 通常适合资源受限的视觉部署,批大小为 1 的 Transformer 解码通常会对内存带宽造成很大压力,但这两种选择都需要在预期运行条件下进行测量。

table 3 中的瓶颈列指出了每类工作负载中限制性能的系统资源:计算吞吐量、内存带宽、内存容量、延迟或功耗。用机器学习系统铁律(机器学习系统铁律)的术语来说,这一瓶颈揭示了是运算量(\(O\))还是数据搬移量(\(D_{\text{vol}}\))主导执行时间,从而决定哪些优化策略仍然有效。

Table 3: 灯塔模型对比:五种典型工作负载的量化特征及其教学作用。内存占用指 FP32 权重的存储空间,FLOPs 按每次推理计,GPT-2 XL 除外,其数值按每个生成词元计;DLRM 行报告的是嵌入表条目数,而非稠密参数量。瓶颈列指出各模型所揭示的主要系统约束:ResNet 等受计算限制的模型对算术吞吐量提出较高要求,而 GPT-2 等受带宽限制的模型则对内存传输速率提出较高要求。
模型 领域 参数量 每次推理的 FLOPs 内存占用 瓶颈 在教材中的作用
ResNet-50 视觉 25.6M 8.2 GFLOP 102.4 MB 计算 稠密视觉计算吞吐量
GPT-2 XL 语言 1.5B 3 GFLOP/token 6 GB 内存带宽 逐词元模型服务
DLRM 推荐系统 25B 低 100 GB 内存容量 嵌入表与容量规划
MobileNetV2 边缘视觉 3.5M 600 MFLOP 14 MB 延迟 逐通道卷积与效率
KWS (DS-CNN) 音频 200K 20 MFLOP 800 KB 功耗 持续运行的功耗预算

架构选择归根结底是数学运算 \((O)\) 与内存数据搬移 \((D_{\text{vol}})\) 之间的工程权衡。table 2 中各项特征背后的机制,解释了每个灯塔为何处于算术强度谱系中的相应位置。ResNet-50 的算术强度较高,是因为卷积层会沿图像的空间维度多次复用每个权重(较深的瓶颈层可达到 100–200+ FLOP/byte),因此其性能受硬件算术吞吐量限制。GPT-2 则位于另一个极端:每生成一个词元仅执行矩阵向量乘法,而非批处理中的矩阵矩阵运算,因此系统要为单个词元的数学运算从内存中加载大量权重,性能受内存带宽限制。从整个模型层面看,MobileNet 位于两者之间;但在计入激活值流量后,单个逐通道卷积层的算术强度会更低:深度可分离卷积减少了总运算量 \(O\),但相对于这些计算工作,需要搬移更多数据。这种特性很适合移动硬件,却常常使针对稠密数学运算优化的高端 GPU“吃不饱”。

Checkpoint 1.1: 算术强度与架构

将架构选择与其系统影响对应起来:

这一谱系决定了系统需要更快的处理器还是更快的内存来提升性能。本书用于量化特定硬件上这些限制的框架是 Roofline 模型,它以算术强度为横轴、可达吞吐量为纵轴绘图,展示工作负载在何处从受内存限制转为受计算限制。Roofline 模型 给出了分析方法,硬件加速 提供了应用示例。具体示例:A100 分析 根据真实加速器的规格,演示了如何由算术强度判定瓶颈:计算 A100 的转折点,并展示同一种操作如何落在该点的任一侧。

这些灯塔特征使下一步分析变得具体:从目标数据模式、执行的计算、形成的硬件映射,以及暴露的瓶颈这四个方面考察每个架构家族。这一四维视角确保对每种架构的评估都考虑其运行成本,而不只关注它能学到什么。

MLP:稠密模式处理

以智能手机上的垃圾邮件过滤器为例:给定从邮件中提取的一组特征(发件人信誉评分、链接数量、是否出现某些关键词),模型必须输出一个概率值,判断邮件是否为垃圾邮件。在这种分类任务中,每个输入特征都与每个输出相连,因而属于全连接网络的应用领域。多层感知机(MLP)3 代表了 神经计算 中介绍的全连接架构,现在我们将通过前文建立的四维系统视角对其进行考察。

MLP 体现了一种归纳偏置:它们假定数据不具有任何先验结构,允许任意输入与任意输出建立关联。这一架构选择将所有输入关系视为同等可能,从而实现最大的灵活性,使 MLP 具有广泛的适用性,但与专用架构相比,其计算开销更大。通用逼近定理(UAT)4 (Cybenko 1989; Hornik et al. 1989) 从理论上确立了它们的表示能力,该定理已在 神经计算 中介绍。该定理指出,只要权重和偏置适当,具有非线性激活函数且规模足够大的 MLP 就能逼近紧致域上的任意连续函数。这种理论上的通用性与稠密连接相结合,构成了多层感知机所体现的架构概念。

Cybenko, George. 1989. “Approximation by Superpositions of a Sigmoidal Function.” Mathematics of Control, Signals, and Systems 2 (4): 303–14. https://doi.org/10.1007/bf02551274.
Hornik, Kurt, Maxwell Stinchcombe, and Halbert White. 1989. “Multilayer Feedforward Networks Are Universal Approximators.” Neural Networks 2 (5): 359–66. https://doi.org/10.1016/0893-6080(89)90020-8.
Definition 1.2: 多层感知机

多层感知机是一类依次应用全连接层的前馈神经网络架构,其中一层中的每个神经元都与下一层中的每个神经元相连,不对输入域编码任何结构性假设。

  1. 意义:由于缺乏结构先验,稠密层的参数量随层宽度呈二次增长:将 1,024 个输入映射到 1,024 个输出的单层需要 1,048,576 parameters,采用 FP16 时,权重约占用 2.1 MB 的内存。将 1,024 个输入通道映射到 1,024 个输出通道的 \(3{\times}3\) 卷积约有 9.4M weights;卷积在图像处理中的优势来自跨位置的空间权重共享,而非缩小通道混合矩阵本身。因此,MLP 对图像等高维结构化输入的处理效率较低。
  2. 区别:卷积神经网络利用空间局部性减少参数量,而 MLP 对所有输入元素一视同仁,因此对于不具有空间或序列结构的表格数据,MLP 是优先选择的架构。
  3. 常见误区:一种常见误解认为,MLP 过于简单,在复杂任务中没有重要作用。MLP 提供了有用的稠密基线模型,但 CNN、循环网络和 Transformer 引入了无法仅归结为权重共享的算子和连接模式。

在实践中,UAT 解释了 MLP 为何能在多种任务中取得成功,同时也揭示了理论能力与实际实现之间的差距。该定理保证存在某个 MLP 能够逼近任意函数,却没有说明所需的网络规模,也没有指导如何确定权重。虽然 MLP 理论上可以解决任意模式识别问题,但这可能需要大到不切实际的网络或难以承受的计算开销。这种理论上的通用性促使人们在表格数据、推荐系统以及输入关系未知的问题中选择 MLP。与此同时,这些实际限制推动了专用架构的发展,它们通过利用数据结构提高计算效率,如 section 1.3、section 1.4 和 section 1.6 所示。

可学习性差距

UAT 保证了数学上的存在性,但架构能够表示什么与梯度下降在实践中能够学到什么之间,存在根本性的差距。

表示能力指架构在资源无限时能够表达的函数;前文介绍的 UAT 保证了 MLP 具有通用表示能力。流形假设5指出,高维数据实际上占据着简单得多的结构,这使得这种能力尤为有效。可学习性指在训练样本和计算预算有限的条件下,梯度下降能否找到良好的权重。一个函数可能可以表示,却在实践中无法学得。

这一区别解释了通用逼近与架构进步之间的表面悖论。ResNet 和 Transformer 等专用架构通过嵌入与数据结构相匹配的归纳偏置来提高可学习性,即使这样做会限制表示能力。

三个因素造成了可学习性差距:

  1. 样本复杂度:UAT 并未给出所需训练样本数量的界。对于 \(28{\times}28\) 图像,MLP 将 784 个像素独立处理,需要指数级数量的样本才能学习空间相关性。CNN 嵌入了局部性偏置,大幅减少了样本需求。从数学上看,MLP 的样本复杂度可能随输入维度呈指数增长,而与数据结构相匹配的架构则可能呈多项式增长。
  2. 参数效率:UAT 保证某个宽度足以实现逼近,但并未给出构造性的界。某些函数类所需的宽度随输入维度迅速增长,而具有匹配的组合结构的架构能够更紧凑地表示这些函数。
  3. 优化难度:即使最优权重存在,梯度下降也可能无法找到它们。在缺乏架构约束的正则化作用时,MLP 的损失曲面呈现复杂的拓扑结构。专用架构通过缩小搜索空间、引入梯度下降可以利用的对称性来改善优化。经典的 MNIST手写数字基准具体展示了表示能力与可学习性之间的这一差距。

Example 1.2: MNIST:表示能力与可学习性
场景:分别使用全连接 MLP 和 CNN 对 \(28{\times}28\) 的 MNIST 数字图像进行分类。

诊断:一个 3 层 MLP 需要 20M 个参数,因为它独立处理全部 784 个输入像素,忽略了空间结构。CNN 使用局部感受野和权重共享,将参数量降至 421.4K(MLP 与 CNN 的参数量之比为 47×)。

系统启示:归纳偏置决定参数效率。将空间局部性纳入模型架构可使参数存储占用降低数个数量级,从而降低推理过程中的 SRAM 内存带宽压力。

可学习性差距引出了本章的核心设计原则:嵌入与数据结构相匹配的归纳偏置。每种架构都以牺牲理论通用性为代价,换取实践中的可学习性。没有免费午餐定理6 (Wolpert and Macready 1997) 对这一权衡进行了形式化描述:有助于某项任务的偏置可能损害另一项任务的表现。CNN 的平移不变性有助于图像分类,却不利于绝对位置具有重要意义的任务。架构选择从根本上说,就是将归纳偏置与数据结构相匹配。

Wolpert, D. H., and W. G. Macready. 1997. “No Free Lunch Theorems for Optimization.” IEEE Transactions on Evolutionary Computation 1 (1): 67–82. https://doi.org/10.1109/4235.585893.

这些理论认识直接转化为工程决策。适当的归纳偏置能够减少参数量(支持边缘部署)、加快收敛(降低训练成本),并形成能够高效映射到专用硬件的结构化计算模式(硬件加速)。一个具有 20M 个参数、无法进行边缘部署的 MLP,可以转变为具有 421.4K 个参数、能够轻松部署的 CNN;通过使架构与数据结构相匹配,实现了 47× 的参数量缩减倍数。要理解哪些场景仍然需要稠密连接,就必须识别那些无法利用结构特征简化处理的数据模式。

模式处理需求

稠密模式处理针对的是输入特征缺乏几何坐标或序列顺序的问题领域。在表格数据集、推荐嵌入或多因子风险模型中,任意输入特征都可能与其他任意特征发生交互。由于数据表示不具有网格或序列结构,网络无法将计算限制在局部空间窗口或序列步骤内。每个输出神经元都必须能够自由组合所有输入特征,再由优化过程确定连接权重。

当使用稠密架构处理 MNIST 这样的图像数据集时,系统会将 \(28{\times}28\) 图像展平为一个无结构的 784 元素向量。舍弃二维空间先验,迫使网络对所有像素对一视同仁。虽然这使该层能够将任意像素与任意类别关联起来,但也要求模型完全通过优化来发现空间邻接关系——这一架构选择直接导向了定义 MLP 的矩阵运算。

算法结构

特征之间的全互连交互要求相邻层的表示之间具有完整连接。在 MLP 中,这体现为一系列全连接层,其中每个神经元都与前一层中的每个神经元相连。稠密连接直接转化为矩阵乘法,即 矩阵乘法表述 中介绍的计算形式,使稠密层能够在并行硬件上执行。Figure 2 展示了每一层如何通过这一核心运算变换其输入。

 \begin{tikzpicture}[line join=round,font=\sffamily]
\tikzset{%
Line/.style={line width=0.35pt,black!60}
}

\tikzset{
  box/.pic={
    \pgfkeys{/box/.cd, #1}
\foreach \x in {1,...,\columns}{
    \foreach \y in {1,...,\rows}{
        %
        \node[draw=black, fill=\ffill, minimum width=\cellsize,
                    minimum height=\cellheight, line width=\linewidth] (cell-\x-\y\br) at (\x*\cellsize,-\y*\cellheight) {};
    }
}
 } }

\pgfkeys{
  /box/.cd,
  cellsize/.store in=\cellsize,
  linewidth/.store in=\linewidth,
  cellheight/.store in=\cellheight,
  columns/.store in=\columns,
  br/.store in=\br,
  ffill/.store in=\ffill,
  rows/.store in=\rows,
  columns=1,
  rows=3,
  br=A,
  ffill=GreenL!22,
  cellsize=8mm,
  cellheight=8mm,
  linewidth=0.75pt
}
\def\radius{4mm}
\pic at (0,0) {box={columns=1,rows=4,br=A}};
\pic at (2,0) {box={columns=5,rows=4,br=B,}};
\pic at (7,4mm) {box={columns=1,rows=5,br=C}};
\pic at (9,4mm) {box={columns=2,rows=5,br=D}};
\pic at (12,-8mm) {box={columns=1,rows=2,br=E}};
%
\foreach \x in {1,...,4}{
\node[fill=green!80!black!80,minimum size=\cellsize,draw, line width=0.75pt]at(cell-2-\x B){};
}
\node[fill=green!80!black!80,minimum size=\cellsize,draw, line width=0.75pt]at(cell-1-2C){};

\begin{scope}[scale=1, every node/.append style={transform shape},
local bounding box=D1,shift={($(cell-1-3A)+(-4.5,-2.6)$)}]
\foreach \x in {1,...,5}{
\coordinate (2ball-\x) at (0,\x);
\shade[shading=ball,ball color=red!50!yellow] (0,\x) circle (\radius);
}
\shade[shading=ball,ball color=green!50!green] (0,4) circle (\radius);

\foreach \x/\i in {2.5/1,3.5/2}{
\coordinate (3ball-\i) at (2,\x);
\shade[shading=ball,ball color=red!50!yellow] (2,\x) circle (\radius)coordinate(3C\i);
}

\foreach \x/\i in  {1.5/1,2.5/2,3.5/3,4.5/4}{
\coordinate (1ball-\i) at (-2,\x);
\shade[shading=ball,ball color=red!50!yellow] (-2,\x) circle (\radius)coordinate(1C\i);
}
% Connect 1. and 2. column
\foreach \x in {1,2,3,4}{
  \foreach \y in {1,2,3,5}{
    \edef\from{1ball-\x}
    \edef\to{2ball-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[Line] (from) -- (to);
  }
}
%red line
\foreach \x in {1,2,3,4}{
  \foreach \y in {4}{
    \edef\from{1ball-\x}
    \edef\to{2ball-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[Line,red] (from) -- (to);
  }
}
% Connect 2. and 3. column
\foreach \x in {1,2,3,4,5}{
  \foreach \y in {1,2}{
    \edef\from{2ball-\x}
    \edef\to{3ball-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[Line] (from) -- node[inner sep=0pt](L\x){}(to);
  }
}
%%
\draw[latex-](L5)--++(30:1)node[above]{加权边};
\draw[latex-](2ball-4)--++(180:2.5)node[left](NE){神经元};
\draw[thick,latex-](cell-2-2B.center)--++(90:1.52)node[above]{加权边};
\draw[thick,latex-](cell-1-2C.center)--++(90:1.52)node[above]{神经元};
%
\node[font=\huge]at($(cell-1-2A.south east)!0.5!(cell-1-2B.south west)$){$\times$};
\node[font=\huge]at($(cell-1-3C.east)!0.5!(cell-1-3D.west)$){$\times$};
%
\node[single arrow, draw=red, fill=red,
      minimum width = 10pt, single arrow head extend=3pt,
      minimum height=7mm]at($(cell-5-2B.south east)!0.5!(cell-1-3C.west)$){};
\node[single arrow, draw=red, fill=red,
      minimum width = 10pt, single arrow head extend=3pt,
      minimum height=7mm]at($(cell-2-3D.east)!0.5!(cell-1-1E.south west)$){};
\end{scope}

\path(NE.west)--++(270:4.0)coordinate(IL1)-|coordinate(HL1)($(1ball-1)!0.4!(2ball-1)$);
\path(NE)--++(270:4.0)-|coordinate(OL1)($(2ball-1)!0.55!(3ball-1)$);
\path(NE)--++(270:4.0)-|coordinate(OL2)($(3ball-1)!0.5!(cell-1-2A.south east)$);
\path(NE)--++(270:4.0)-|coordinate(IL2)($(3ball-1)!0.6!(cell-1-2A.south east)$);

\path[blue, line width=2pt](IL2)-|coordinate(HL2)($(cell-1-2A.south east)!0.7!(cell-1-2B.south west)$);
\path[blue, line width=2pt](IL2)-|coordinate(OL3)($(cell-1-3C.east)!0.5!(cell-1-3D.west)$);
\path[blue, line width=2pt](IL2)-|coordinate(OL4)(cell-1-2E.south east);

\draw[red,line width=2pt](IL1)--node[below,text=black]{输入层}(HL1);
\draw[cyan,line width=2pt](HL1)--node[below,text=black]{隐藏层}(OL1);
\draw[brown,line width=2pt](OL1)--node[below,text=black]{输出层}(OL2);
%
\draw[red,line width=2pt](IL2)--node[below,text=black]{输入层}(HL2);
\draw[cyan,line width=2pt](HL2)--node[below,text=black]{隐藏层}(OL3);
\draw[brown,line width=2pt](OL3)--node[below,text=black]{输出层}(OL4);
\end{tikzpicture}
Figure 2: 多层感知机架构:一个三层网络,其中每个神经元都与相邻层中的所有神经元相连。高亮显示的神经元接收来自所有输入的加权贡献,展示了通过矩阵乘法实现的稠密 \(\mathcal{O}(N \times M)\) 连接模式。对于 MNIST 分类,784 维输入通过一个 \(784{\times}100\) 权重矩阵连接到 100 个隐藏神经元,每个样本需要 78,400 次乘加运算。改编自 (Reagen et al. 2017)。
Reagen, Brandon, Robert Adolf, Paul Whatmough, Gu-Yeon Wei, and David Brooks. 2017. Deep Learning for Computer Architects. Synthesis Lectures on Computer Architecture. Springer International Publishing. https://doi.org/10.1007/978-3-031-01756-8.

Equation 1 表示稠密层的仿射变换及其后的激活运算。 \[ \mathbf{h}^{(\ell)} = f\big(\mathbf{h}^{(\ell-1)}\mathbf{W}^{(\ell)} + \mathbf{b}^{(\ell)}\big) \tag{1}\]

\(\mathbf{h}^{(\ell)}\) 表示第 \(\ell\) 层的输出,\(\mathbf{h}^{(\ell-1)}\) 表示来自前一层的输入,\(\mathbf{W}^{(\ell)}\) 表示第 \(\ell\) 层的权重矩阵,\(\mathbf{b}^{(\ell)}\) 表示偏置向量,\(f(\cdot)\) 表示激活函数;非线性激活函数 详细阐述了修正线性单元(ReLU)及相关非线性函数。这种逐层变换在概念上虽然简单,但会形成特定的计算模式,其效率在很大程度上取决于运行时如何针对不同的问题结构组织这些操作。

这些操作的维度揭示了稠密模式处理的计算规模。输入向量 \(\mathbf{h}^{(0)} \in \mathbb{R}^{d_{\text{in}}}\)(在此表述中视为行向量)表示所有潜在的输入特征。权重矩阵 \(\mathbf{W}^{(\ell)} \in \mathbb{R}^{d_{\text{in}} \times d_{\text{out}}}\) 刻画所有可能的输入—输出关系。输出向量 \(\mathbf{h}^{(\ell)} \in \mathbb{R}^{d_{\text{out}}}\) 给出变换后的表示。下面用一个四像素示例将这些维度关系转化为具体运算。

Example 1.3: 具体计算示例
考虑一幅简化的 4 像素图像,由包含 3 个神经元的隐藏层处理:

输入:\(\mathbf{h}^{(0)} = [0.8, 0.2, 0.9, 0.1]\)(4 个像素强度值)

权重矩阵: \[ \mathbf{W}^{(1)} = \begin{bmatrix} 0.5 & 0.1 & -0.2 \\ -0.3 & 0.8 & 0.4 \\ 0.2 & -0.4 & 0.6 \\ 0.7 & 0.3 & -0.1 \end{bmatrix}\quad (4{\times}3 \text{ matrix}) \]

计算: \[\begin{gather*} \mathbf{z}^{(1)} = \mathbf{h}^{(0)}\mathbf{W}^{(1)} = \begin{bmatrix} 0.5{\times}0.8 + (-0.3)\times 0.2 + 0.2{\times}0.9 + 0.7{\times}0.1 \\ 0.1{\times}0.8 + 0.8{\times}0.2 + (-0.4)\times 0.9 + 0.3{\times}0.1 \\ (-0.2)\times 0.8 + 0.4{\times}0.2 + 0.6{\times}0.9 + (-0.1)\times 0.1 \end{bmatrix} = \begin{bmatrix} 0.59 \\ -0.09 \\ 0.45 \end{bmatrix} \end{gather*}\] 经过 ReLU 后:\(\mathbf{h}^{(1)} = [0.59, 0, 0.45]\)(负值置零)

系统层面的启示:每个隐藏神经元以不同的权重组合所有输入像素,体现了不受限制的特征交互。稠密层以最高的连接成本换取通用性。

MNIST 示例使这一规模变得具体。784 维输入连接到第一个隐藏层中的每个神经元。包含 100 个神经元的隐藏层需要一个 \(784{\times}100\) 的权重矩阵(78,400 个参数),其中每个权重表示输入像素与隐藏特征之间的一种可学习关系。本章的计算分析始终以这一单层为基准。

这种算法结构支持任意特征关系,同时也形成了计算机系统必须适应的特定计算模式。稠密连接提供了前文确立的通用逼近能力,但也引入了计算冗余:尽管理论上 MLP 在宽度足够时能够建模任意连续函数,这种灵活性却需要大量参数来学习相对简单的模式。每个输入特征都会影响每个输出,以最高的计算开销换取最大的表达能力。这些权衡推动了后续压缩策略的发展,旨在保持模型能力的同时降低计算需求;硬件加速 则探讨了利用规则矩阵运算结构的硬件专用实现。

计算映射

Section 1.2.3 定义了 MLP 计算的内容;计算映射则揭示了这些计算如何转化为硬件操作。Listing 1 展示了这一映射如何从数学抽象推进到实际计算。

Listing 1: 矩阵形式的 MLP 层:框架级矩阵运算将 \(\mathcal{O}(B \times d_{\text{in}} \times d_{\text{out}})\) 的乘加复杂度封装在一次函数调用中,使针对硬件优化的 BLAS 库能够高效利用稠密矩阵硬件。
def mlp_layer_matrix(X, W, b):
    """MLP forward pass using framework-level matrix operations."""
    # X: input matrix (batch_size by num_inputs)
    # W: weight matrix (num_inputs by num_outputs)
    # b: bias vector (num_outputs)

    # Single GEMM call: frameworks dispatch to optimized BLAS/cuBLAS
    # For MNIST: 784 * 100 = 78,400 MACs per sample
    H = activation(matmul(X, W) + b)
    return H

函数 mlp_layer_matrix 直接对应数学方程,使用高级矩阵运算(matmul)在一行中表达计算,同时封装底层复杂性。这种实现方式是深度学习框架的典型特征,实际计算由优化库负责。

output = matmul(X, W) 等框架操作抽象了物理执行过程。从硬件角度看,稠密矩阵乘法会被降级为典型的三重嵌套循环,它决定了内存访问局部性、并行化边界和寄存器利用率。

listing 2 中的实现直接展示了这一执行模式。计算层输出时,需要针对批次中的每个样本,累加所有输入的加权贡献。最外层循环遍历批次样本,中间层循环遍历输出神经元,最内层循环反复执行乘加(MAC)操作7,将每个输入特征与其对应参数配对。

Listing 2: 稠密层计算:嵌套循环揭示了 \(\mathcal{O}(B \times d_{\text{out}} \times d_{\text{in}})\) 的复杂度,其中每个输出神经元需要 num_inputs 次乘加操作,因此作为基准的 MNIST 输入层每个样本需要 78,400 次 MAC。
def mlp_layer_compute(X, W, b):
    """Explicit loop structure exposing MLP computational patterns."""
    # Loop 1: Process each sample independently (parallelizable)
    for batch in range(batch_size):
        # Loop 2: Compute each output neuron
        for out in range(num_outputs):
            Z[batch, out] = b[out]  # Initialize with bias

            # Loop 3: Accumulate weighted inputs (innermost loop)
            # This is the MAC operation: result += input * weight
            for in_ in range(num_inputs):
                Z[batch, out] += X[batch, in_] * W[in_, out]
            # Total per output: num_inputs MACs +
            # num_inputs memory reads

    H = activation(Z)  # Element-wise nonlinearity
    return H

在作为基准的 MNIST 层中,计算 100 个隐藏神经元总共需要 78,400 MACs;每个输出神经元需要 784 次乘加操作,以及至少 1,568 次内存访问(784 次读取输入,784 次读取权重)。生产环境中的实现会调用基本线性代数子程序(BLAS)等优化矩阵库,8 但同样的嵌套循环模式仍然决定着系统设计问题。用于加速这些矩阵运算的硬件架构,包括 GPU Tensor Core9 和专用 AI 加速器,将在 硬件加速 中介绍。

系统层面的影响

稠密模式处理将硬件压力集中在三个维度:用于参数存储的内存容量、矩阵引擎的计算吞吐量,以及用于权重搬运的内存带宽。

这三种约束均源于全连接。内存占用主要来自参数存储。虽然作为基准的 MNIST 层 \((784{\times}100)\) 仅需要 78,400 个参数,但对于较宽的隐藏状态,\(\mathcal{O}(M \times N)\) 的规模增长会使成本难以承受。一个连接 2048 个输入与 2048 个输出的层需要 4,194,304 parameters(采用 FP32 时占用 16.8 MB)。由于在单样本推理中,每个输入向量都需要读取每个权重一次,因此无法在不同输入之间复用权重,使执行受限于内存容量和带宽。

核心计算是稠密 GEMV,批处理时则是 GEMM。这种计算规则且可并行化,但在小批次下算术强度(FLOP/byte)较低。批大小 是一起处理的输入样本数量;更大的批次可将权重加载成本分摊到更多计算上。现代处理器通过单指令多数据(SIMD)单元(例如 CPU 上的 AVX-512),或张量处理单元(TPU)和 GPU 上的脉动阵列来优化稠密层,将控制开销分摊到大块并行算术运算上。

由此产生的瓶颈是数据移动。要从 784 个输入计算出 100 个隐藏值,系统必须将 \(784{\times}100\) 个权重从内存搬运到计算单元。将 section 1.1.2 中的算术强度分析框架应用于这一层,批大小为 1 的 FP32 执行的算术强度约为 0.5 FLOP/byte。在仅考虑权重的模型中,每个权重计入一次 FP32 读取,忽略输入、输出、偏置和缓存流量,equation 2 给出了这一比值,其中 \(M\) 和 \(N\) 分别为输入和输出宽度。 \[ \text{Intensity} \approx \frac{2 \cdot M \cdot N \text{ FLOPs}}{4 \cdot M \cdot N \text{ bytes}} = 0.5 \text{ FLOP/byte} \tag{2}\]

对于转折点达到数百 FLOP/byte 的加速器,这个批大小为 1 的 FP32 层受内存带宽限制。批处理可以通过分摊权重流量来提高算术强度,但从内存受限转向计算受限的临界点取决于矩阵形状、精度、实现和硬件。具体而言,将批大小增加到 \(B\),会使算术运算量增加到 \(2 \cdot B \cdot M \cdot N\) FLOPs,而权重矩阵只加载一次(\(4 \cdot M \cdot N\) 字节),使受权重流量约束的算术强度提升至 \(\text{Intensity} \approx 0.5 B \text{ FLOP/byte}\),直到输入和激活流量开始占据主导地位。这就是全连接层尽管总 FLOPs 少于卷积层,却仍可能成为推理瓶颈的原因。

两条采用对数刻度的水平参数量条形,分别标注为全连接 205M 和卷积 37K,全连接条形明显更长。

权重共享使卷积避免了全连接所带来的参数量爆炸。

因此,稠密连接以最多的数据移动支撑最少的计算。 对于具有内在结构的数据(例如图像中的空间局部性或序列中的时间顺序),专用架构可以利用这些结构,同时提高准确率和效率。其中最成熟的架构是卷积神经网络。

CNN:空间模式处理

MLP 假设每个输入都可能与每个输出直接交互,对于图像这类具有空间结构的数据,这一假设的代价尤为高昂。将高分辨率输入中的每个像素连接到每个隐藏单元,会产生难以管理的参数存储需求,耗尽加速器内存,并使算术强度降低,导致执行受内存带宽限制而变得缓慢。正如前文 MNIST 对比所展示的那样,示例 CNN 利用空间局部性,而非独立处理每个像素,使所需参数量缩减了 47× 倍。

CNN10 将这种计算权衡直接落实到芯片实现中 (LeCun et al. 1998; Krizhevsky et al. 2012)。CNN 不显式构建全连接矩阵,而是将每个输出激活限制在局部空间区域内,并在整个输入范围上滑动相同的滤波器权重。

这种空间归纳偏置转化为计算图上的两项结构性约束。参数共享在每个空间位置应用同一组小型滤波器权重,将参数存储从数百万个不同权重缩减为能够容纳于片上缓存的紧凑卷积核。局部连接将每个神经元的感受野限制在空间相邻的邻域内,消除了对远距离、不相关像素的计算。这两项约束共同定义了卷积架构族。

Definition 1.3: 卷积神经网络

卷积神经网络(CNN) 是一类利用平移等变性和空间局部性、在所有空间位置共享所学习滤波器的架构,从而使参数量与输入分辨率解耦。

  1. 意义:权重共享 大幅减少了参数量。一个具有 64 个输入通道和 64 个输出通道的 \(3{\times}3\) 卷积层需要 \(3 \times 3 \times 64 \times 64 \approx 37{,}000\) 个参数,无论输入图像是 \(224{\times}224\) 还是 \(1024{\times}1024\)。对于 \(224{\times}224{\times}64\) 的输入,等效的全连接层需要 \(224^2 \times 64 \times 64 \approx 205\) 百万个参数,两者相差约 5,575\(\times\)。这种参数量保持恒定的扩展特性,使 CNN 能够在单个加速器的内存预算内处理高分辨率输入。
  2. 区别:MLP 将每个输入元素连接到每个输出元素(全局连接),而 CNN 将每个输出限制在局部空间邻域内,将邻近像素比远距离像素更相关这一假设编码到架构中。这种限制在架构设计阶段就排除了整类假设,而不是在训练期间对其施加惩罚。
  3. 常见误区:一种常见误解是 CNN 仅适用于视觉模型。卷积运算适用于任何具有网格状拓扑的数据:一维卷积处理音频波形和时间序列,二维卷积处理图像和频谱图,三维卷积处理视频和体数据。

这种权衡十分明确:当数据具有已知结构时,CNN 以牺牲 MLP 的理论通用性为代价,换取实际效率提升。MLP 独立对待每个输入元素,而 CNN 利用空间关系,在视觉任务中同时节省计算并提高准确率。

模式处理需求

空间模式处理面向数据点之间的相关性随几何距离增大而迅速衰减的工作负载。在自然图像中,像素与相邻像素的协方差较高,因此能够检测边缘、纹理和轮廓等局部基元。堆叠这些操作,可以使局部基元按层次组合为更高级的表示:边缘组合成轮廓,轮廓组合成表面片,表面片再组合成完整物体。figure 3 中的处理流程以具体的可视化形式展示了这一层次结构。

\begin{tikzpicture}[line join=round,font=\sffamily]
\tikzset{
 Line/.style={line width=0.5pt,black!50,text=black},
 LineD/.style={line width=0.5pt,black!50,text=black,dashed},
}

\tikzset{
channel/.pic={
\pgfkeys{/channel/.cd, #1}
\begin{scope}[yscale=\scalefac,xscale=\scalefac,every node/.append style={scale=\scalefac}]
\node[rectangle,draw=\channelcolor,line width=1pt,fill=\channelcolor!10,
minimum width=46,minimum height=56](\picname){};
\end{scope}
        }
}

\pgfkeys{
  /channel/.cd,
  channelcolor/.store in=\channelcolor,
  scalefac/.store in=\scalefac,
  picname/.store in=\picname,
  channelcolor=BrownLine,
  scalefac=1,
  picname=C
}
%circles sty
\tikzset{
circles/.pic={
\pgfkeys{/channel/.cd, #1}
\node[circle,draw=\channelcolor,line width=1pt,fill=\channelcolor!10,
minimum size=6mm](\picname){};
        }
}
%Zebra sty
\tikzset{
zebra/.pic={
\pgfkeys{/zebra/.cd, #1}
\definecolor{cfefefe}{RGB}{254,254,254}
\definecolor{c373435}{RGB}{55,52,53}
\begin{scope}[yscale=\globalscale,xscale=\globalscale,every node/.append style={scale=\globalscale}]
\path[fill=c373435,shift={(9.6358, -1.7033)}] (0.0, 31.4325).. controls (0.0427, 31.4009) and (0.0852, 31.369) .. (0.1273, 31.3366).. controls (0.1423, 31.3254) and (0.1573, 31.3141) .. (0.1728, 31.3026).. controls (0.2651, 31.2301) and (0.3393, 31.1462) .. (0.4151, 31.0574).. controls (0.4863, 30.9754) and (0.5596, 30.8955) .. (0.6333, 30.8157).. controls (0.6467, 30.8012) and (0.66, 30.7868) .. (0.6737, 30.7719).. controls (0.7542, 30.6847) and (0.8368, 30.6) .. (0.9211, 30.5164).. controls (0.9461, 30.4904) and (0.9461, 30.4904) .. (0.9717, 30.4639).. controls (0.9867, 30.4485) and (1.0016, 30.433) .. (1.017, 30.4172).. controls (1.0321, 30.4015) and (1.0471, 30.3858) .. (1.0627, 30.3696).. controls (1.1076, 30.325) and (1.1076, 30.325) .. (1.1857, 30.3047).. controls (1.1773, 30.338) and (1.169, 30.3713) .. (1.1604, 30.4056).. controls (1.0895, 30.6895) and (1.0185, 30.9733) .. (0.9475, 31.2572).. controls (0.9423, 31.2765) and (0.9371, 31.2958) .. (0.9317, 31.3157).. controls (0.9141, 31.3941) and (0.9166, 31.4684) .. (0.9211, 31.5483).. controls (0.9924, 31.6196) and (1.0315, 31.6099) .. (1.1311, 31.6111).. controls (1.5189, 31.6038) and (1.7672, 31.4046) .. (2.0276, 31.1361).. controls (2.5302, 30.5776) and (2.7987, 29.8516) .. (2.9904, 29.1373).. controls (3.0848, 28.7935) and (3.1926, 28.4518) .. (3.3106, 28.1153).. controls (3.3197, 28.0891) and (3.3197, 28.0891) .. (3.329, 28.0624).. controls (3.3457, 28.0158) and (3.3637, 27.9696) .. (3.3817, 27.9235).. controls (3.3965, 27.8817) and (3.3965, 27.8817) .. (3.4117, 27.839).. controls (3.4831, 27.7316) and (3.5705, 27.7011) .. (3.6876, 27.6539).. controls (3.7178, 27.6408) and (3.7178, 27.6408) .. (3.7487, 27.6275).. controls (3.8966, 27.5649) and (4.0474, 27.5172) .. (4.2019, 27.4737).. controls (4.1102, 27.846) and (4.0172, 28.2179) .. (3.9175, 28.5882).. controls (3.91, 28.6159) and (3.9026, 28.6436) .. (3.8949, 28.6721).. controls (3.8319, 28.9046) and (3.7693, 29.1311) .. (3.6727, 29.3522).. controls (3.6329, 29.4621) and (3.596, 29.5729) .. (3.5588, 29.6837).. controls (3.5098, 29.8269) and (3.4523, 29.9591) .. (3.3817, 30.093).. controls (3.333, 30.0443) and (3.3518, 29.9759) .. (3.3516, 29.911).. controls (3.3516, 29.8892) and (3.3517, 29.8673) .. (3.3517, 29.8448).. controls (3.3517, 29.8224) and (3.3517, 29.7999) .. (3.3517, 29.7768).. controls (3.3516, 29.7292) and (3.3517, 29.6815) .. (3.3518, 29.6339).. controls (3.3519, 29.5614) and (3.3518, 29.489) .. (3.3516, 29.4165).. controls (3.3516, 29.3702) and (3.3517, 29.3239) .. (3.3517, 29.2776).. controls (3.3517, 29.2453) and (3.3517, 29.2453) .. (3.3516, 29.2123).. controls (3.3521, 29.0889) and (3.362, 28.9717) .. (3.3817, 28.8495).. controls (3.3833, 28.806) and (3.384, 28.7624) .. (3.3834, 28.7189).. controls (3.3831, 28.6984) and (3.3829, 28.678) .. (3.3826, 28.657).. controls (3.3822, 28.6344) and (3.3822, 28.6344) .. (3.3817, 28.6114).. controls (3.2533, 28.7619) and (3.185, 28.9226) .. (3.1237, 29.1091).. controls (3.117, 29.1295) and (3.1103, 29.1498) .. (3.1034, 29.1708).. controls (2.925, 29.7222) and (2.7421, 30.3033) .. (2.7202, 30.8868).. controls (2.7192, 30.9105) and (2.7181, 30.9341) .. (2.717, 30.9585).. controls (2.7124, 31.1535) and (2.7119, 31.3674) .. (2.815, 31.5382).. controls (2.8862, 31.6082) and (2.9232, 31.6166) .. (3.0215, 31.6176).. controls (3.0495, 31.6169) and (3.0495, 31.6169) .. (3.078, 31.6162).. controls (3.1079, 31.6162) and (3.1079, 31.6162) .. (3.1383, 31.6162).. controls (3.2039, 31.6162) and (3.2694, 31.6151) .. (3.335, 31.6141).. controls (3.3805, 31.6138) and (3.426, 31.6137) .. (3.4716, 31.6135).. controls (3.5913, 31.613) and (3.711, 31.6117) .. (3.8307, 31.6103).. controls (3.9529, 31.6089) and (4.0751, 31.6083) .. (4.1973, 31.6076).. controls (4.4369, 31.6062) and (4.6766, 31.604) .. (4.9163, 31.6012).. controls (4.9378, 31.4702) and (4.943, 31.4044) .. (4.8898, 31.2837).. controls (4.8421, 31.0837) and (4.8146, 30.8783) .. (4.784, 30.6751).. controls (4.7798, 30.6479) and (4.7757, 30.6206) .. (4.7714, 30.5925).. controls (4.6406, 29.6875) and (4.6362, 28.7165) .. (4.8105, 27.8176).. controls (4.8151, 27.7934) and (4.8198, 27.7691) .. (4.8246, 27.7441).. controls (4.8499, 27.6171) and (4.8772, 27.4915) .. (4.9163, 27.3678).. controls (4.9244, 27.3406) and (4.9326, 27.3133) .. (4.941, 27.2852).. controls (5.0799, 27.0918) and (5.3945, 27.0356) .. (5.6125, 26.9643).. controls (5.6401, 26.9551) and (5.6678, 26.9458) .. (5.6962, 26.9362).. controls (5.8245, 26.8938) and (5.9465, 26.8586) .. (6.0805, 26.8387).. controls (6.0841, 27.0916) and (6.0745, 27.3411) .. (6.0578, 27.5934).. controls (6.0091, 28.3459) and (6.0394, 29.0783) .. (6.1069, 29.8285).. controls (6.1097, 29.8596) and (6.1125, 29.8908) .. (6.1154, 29.9229).. controls (6.1213, 29.9885) and (6.1273, 30.054) .. (6.1334, 30.1195).. controls (5.5664, 29.5624) and (5.3134, 28.8614) .. (5.2083, 28.0876).. controls (5.1945, 27.9896) and (5.1837, 27.9277) .. (5.128, 27.8441).. controls (5.0486, 27.8705) and (5.0486, 27.8705) .. (5.0205, 27.9238).. controls (4.7982, 28.558) and (4.7702, 29.2746) .. (4.8898, 29.9343).. controls (4.8957, 29.9715) and (4.9015, 30.0087) .. (4.9073, 30.0459).. controls (4.9939, 30.59) and (5.1647, 31.1603) .. (5.5777, 31.5483).. controls (5.6618, 31.5998) and (5.7256, 31.6079) .. (5.8235, 31.608).. controls (5.8514, 31.6082) and (5.8793, 31.6084) .. (5.908, 31.6085).. controls (5.953, 31.6084) and (5.953, 31.6084) .. (5.9988, 31.6082).. controls (6.0297, 31.6083) and (6.0605, 31.6083) .. (6.0923, 31.6084).. controls (6.1575, 31.6084) and (6.2226, 31.6083) .. (6.2878, 31.6081).. controls (6.3878, 31.6078) and (6.4879, 31.6081) .. (6.5879, 31.6084).. controls (6.6512, 31.6084) and (6.7144, 31.6083) .. (6.7777, 31.6082).. controls (6.8077, 31.6083) and (6.8378, 31.6084) .. (6.8688, 31.6085).. controls (6.8965, 31.6084) and (6.9242, 31.6082) .. (6.9528, 31.608).. controls (6.9773, 31.608) and (7.0018, 31.6079) .. (7.027, 31.6079).. controls (7.0859, 31.6012) and (7.0859, 31.6012) .. (7.1388, 31.5483).. controls (7.1293, 31.4369) and (7.0978, 31.344) .. (7.0535, 31.2421).. controls (7.0416, 31.2143) and (7.0296, 31.1865) .. (7.0172, 31.1578).. controls (7.0044, 31.1284) and (6.9916, 31.099) .. (6.9784, 31.0687).. controls (6.9519, 31.0068) and (6.9254, 30.9449) .. (6.8989, 30.883).. controls (6.8858, 30.8523) and (6.8726, 30.8217) .. (6.8591, 30.7901).. controls (6.657, 30.3214) and (6.657, 30.3214) .. (6.5302, 29.8285).. controls (6.6047, 29.8946) and (6.6473, 29.9684) .. (6.6956, 30.055).. controls (6.8695, 30.358) and (6.8695, 30.358) .. (6.98, 30.4899).. controls (6.9975, 30.4899) and (7.015, 30.4899) .. (7.033, 30.4899).. controls (7.0396, 30.5053) and (7.0462, 30.5206) .. (7.053, 30.5364).. controls (7.1877, 30.7796) and (7.478, 30.912) .. (7.7299, 30.9954).. controls (8.1759, 31.1044) and (8.8968, 31.0899) .. (9.3084, 30.8603).. controls (9.3067, 30.8137) and (9.3067, 30.8137) .. (9.2819, 30.7545).. controls (9.2203, 30.7164) and (9.1617, 30.6847) .. (9.0967, 30.6536).. controls (8.9312, 30.5703) and (8.7884, 30.478) .. (8.6469, 30.3576).. controls (8.625, 30.3412) and (8.6031, 30.3247) .. (8.5805, 30.3077).. controls (8.3838, 30.1407) and (8.3003, 29.9209) .. (8.2765, 29.6697).. controls (8.3561, 29.6457) and (8.398, 29.6394) .. (8.4772, 29.668).. controls (8.5016, 29.6811) and (8.5259, 29.6942) .. (8.551, 29.7077).. controls (8.5789, 29.7225) and (8.6069, 29.7372) .. (8.6356, 29.7524).. controls (8.6813, 29.7774) and (8.7269, 29.8023) .. (8.7724, 29.8274).. controls (9.4666, 30.2093) and (10.2314, 30.4734) .. (11.0329, 30.3266).. controls (11.097, 30.2975) and (11.1092, 30.263) .. (11.134, 30.1989).. controls (11.049, 30.1023) and (10.9533, 30.0499) .. (10.8396, 29.9938).. controls (10.5212, 29.8296) and (10.2005, 29.5968) .. (10.0657, 29.2515).. controls (10.0287, 29.1214) and (10.0299, 29.0228) .. (10.0889, 28.8975).. controls (10.2892, 28.6722) and (10.5797, 28.5947) .. (10.8694, 28.5585).. controls (10.9985, 28.5519) and (11.1272, 28.5506) .. (11.2564, 28.5504).. controls (11.3207, 28.5503) and (11.385, 28.5498) .. (11.4493, 28.5493).. controls (11.6319, 28.5479) and (11.8146, 28.547) .. (11.9972, 28.5464).. controls (12.9803, 28.5425) and (12.9803, 28.5425) .. (13.4094, 28.4526).. controls (13.452, 28.4443) and (13.4946, 28.436) .. (13.5371, 28.4277).. controls (13.9198, 28.3531) and (14.3389, 28.2446) .. (14.653, 28.0028).. controls (14.6878, 27.9443) and (14.6878, 27.9443) .. (14.7059, 27.897).. controls (14.6377, 27.8114) and (14.5751, 27.8014) .. (14.4694, 27.7829).. controls (13.8545, 27.6612) and (13.2491, 27.4341) .. (12.748, 27.0503).. controls (12.7392, 27.0329) and (12.7305, 27.0154) .. (12.7215, 26.9974).. controls (12.8098, 27.0097) and (12.8978, 27.0223) .. (12.9856, 27.038).. controls (13.6213, 27.1426) and (14.2736, 27.0902) .. (14.8911, 26.918).. controls (14.9199, 26.9102) and (14.9487, 26.9023) .. (14.9783, 26.8942).. controls (15.4527, 26.7567) and (16.2756, 26.4887) .. (16.5406, 26.0373).. controls (16.5463, 26.0223) and (16.5521, 26.0074) .. (16.558, 25.992).. controls (16.5315, 25.9655) and (16.5315, 25.9655) .. (16.4637, 25.9646).. controls (16.4337, 25.9656) and (16.4037, 25.9666) .. (16.3727, 25.9676).. controls (15.7533, 25.9821) and (15.1624, 25.9354) .. (14.6, 25.648).. controls (14.5826, 25.6306) and (14.5651, 25.6131) .. (14.5471, 25.5951).. controls (14.6676, 25.61) and (14.788, 25.6255) .. (14.9083, 25.6415).. controls (15.9588, 25.7788) and (16.89, 25.6242) .. (17.7543, 24.9708).. controls (18.3652, 24.4899) and (18.3652, 24.4899) .. (18.4303, 24.2506).. controls (18.4323, 24.2315) and (18.4344, 24.2125) .. (18.4365, 24.1928).. controls (18.3358, 24.1661) and (18.2779, 24.1685) .. (18.1802, 24.2028).. controls (17.8648, 24.2951) and (17.5116, 24.298) .. (17.193, 24.2193).. controls (17.1842, 24.2106) and (17.1755, 24.2018) .. (17.1665, 24.1928).. controls (17.1819, 24.1897) and (17.1973, 24.1865) .. (17.2132, 24.1832).. controls (17.5439, 24.1141) and (17.8621, 24.0379) .. (18.1719, 23.9018).. controls (18.189, 23.8943) and (18.2061, 23.8869) .. (18.2237, 23.8792).. controls (18.4411, 23.7823) and (18.6401, 23.6661) .. (18.835, 23.5297).. controls (18.8624, 23.5106) and (18.8624, 23.5106) .. (18.8904, 23.4911).. controls (19.0158, 23.4005) and (19.1233, 23.299) .. (19.2302, 23.1874).. controls (19.2521, 23.1661) and (19.2739, 23.1449) .. (19.2964, 23.1229).. controls (19.3182, 23.1006) and (19.34, 23.0782) .. (19.3625, 23.0551).. controls (19.3791, 23.0381) and (19.3957, 23.0212) .. (19.4128, 23.0037).. controls (19.43, 22.9852) and (19.4473, 22.9667) .. (19.4651, 22.9476).. controls (19.4814, 22.9304) and (19.4977, 22.9132) .. (19.5145, 22.8955).. controls (19.5477, 22.8435) and (19.5477, 22.8435) .. (19.5366, 22.7873).. controls (19.529, 22.7627) and (19.529, 22.7627) .. (19.5213, 22.7376).. controls (19.4998, 22.737) and (19.4783, 22.7363) .. (19.4562, 22.7356).. controls (19.3583, 22.7325) and (19.2604, 22.7293) .. (19.1624, 22.7261).. controls (19.1287, 22.725) and (19.0949, 22.724) .. (19.0601, 22.7229).. controls (19.0272, 22.7218) and (18.9944, 22.7207) .. (18.9606, 22.7195).. controls (18.9305, 22.7186) and (18.9005, 22.7176) .. (18.8695, 22.7166).. controls (18.7077, 22.7178) and (18.7077, 22.7178) .. (18.5688, 22.6583).. controls (18.5966, 22.6555) and (18.5966, 22.6555) .. (18.6249, 22.6526).. controls (18.7104, 22.6439) and (18.7959, 22.6345) .. (18.8813, 22.6252).. controls (18.925, 22.6208) and (18.925, 22.6208) .. (18.9695, 22.6164).. controls (19.4656, 22.5608) and (19.4656, 22.5608) .. (19.6007, 22.3937).. controls (19.6309, 22.3029) and (19.6325, 22.2297) .. (19.6337, 22.134).. controls (19.6344, 22.1022) and (19.6351, 22.0704) .. (19.6358, 22.0376).. controls (19.6223, 21.8917) and (19.5745, 21.8028) .. (19.4643, 21.7085).. controls (19.4312, 21.6825) and (19.3978, 21.6568) .. (19.3642, 21.6313).. controls (19.3465, 21.6176) and (19.3288, 21.6039) .. (19.3106, 21.5897).. controls (19.2576, 21.5487) and (19.2043, 21.5081) .. (19.1509, 21.4676).. controls (19.136, 21.4563) and (19.1212, 21.445) .. (19.106, 21.4333).. controls (18.9705, 21.3299) and (18.8332, 21.2293) .. (18.6945, 21.1303).. controls (18.496, 20.9865) and (18.3078, 20.83) .. (18.119, 20.6739).. controls (18.1021, 20.6599) and (18.0852, 20.646) .. (18.0677, 20.6317).. controls (18.0202, 20.5924) and (17.9728, 20.553) .. (17.9255, 20.5135).. controls (17.9044, 20.496) and (17.9044, 20.496) .. (17.8828, 20.4781).. controls (17.8105, 20.4172) and (17.7432, 20.3595) .. (17.6957, 20.277).. controls (17.7044, 20.2508) and (17.7131, 20.2246) .. (17.7221, 20.1976).. controls (17.7396, 20.1976) and (17.757, 20.1976) .. (17.775, 20.1976).. controls (17.775, 20.1802) and (17.775, 20.1627) .. (17.775, 20.1447).. controls (17.8451, 20.1072) and (17.9095, 20.0834) .. (17.9867, 20.0653).. controls (18.0264, 20.1127) and (18.0661, 20.1601) .. (18.1058, 20.2076).. controls (18.118, 20.2221) and (18.1301, 20.2366) .. (18.1427, 20.2516).. controls (18.213, 20.3358) and (18.2808, 20.4212) .. (18.3472, 20.5085).. controls (18.5772, 20.7975) and (18.854, 21.0633) .. (19.1509, 21.2824).. controls (19.1881, 21.3119) and (19.1881, 21.3119) .. (19.226, 21.342).. controls (19.2641, 21.3714) and (19.2641, 21.3714) .. (19.303, 21.4015).. controls (19.3258, 21.4192) and (19.3486, 21.437) .. (19.372, 21.4552).. controls (19.4544, 21.501) and (19.5078, 21.5017) .. (19.6007, 21.4941).. controls (19.6325, 21.4305) and (19.6319, 21.3878) .. (19.6339, 21.3168).. controls (19.6347, 21.2909) and (19.6354, 21.265) .. (19.6362, 21.2383).. controls (19.6388, 21.1187) and (19.6408, 20.9991) .. (19.6422, 20.8796).. controls (19.6432, 20.8168) and (19.6446, 20.7541) .. (19.6465, 20.6914).. controls (19.6656, 20.0634) and (19.6656, 20.0634) .. (19.4491, 19.811).. controls (19.4293, 19.7902) and (19.4094, 19.7693) .. (19.389, 19.7478).. controls (19.3653, 19.7155) and (19.3422, 19.6827) .. (19.3202, 19.6492).. controls (19.2937, 19.6113) and (19.2937, 19.6113) .. (19.2666, 19.5726).. controls (19.228, 19.5164) and (19.1894, 19.4601) .. (19.1509, 19.4039).. controls (19.1226, 19.3635) and (19.1226, 19.3635) .. (19.0938, 19.3222).. controls (19.0766, 19.2968) and (19.0594, 19.2713) .. (19.0417, 19.2451).. controls (19.0264, 19.2228) and (19.011, 19.2004) .. (18.9952, 19.1773).. controls (18.9582, 19.0967) and (18.9622, 19.0634) .. (18.9921, 18.9805).. controls (19.0305, 18.921) and (19.0305, 18.921) .. (19.0798, 18.8681).. controls (19.0955, 18.85) and (19.1112, 18.8318) .. (19.1274, 18.8131).. controls (19.1805, 18.7661) and (19.2139, 18.7528) .. (19.2832, 18.7424).. controls (19.3076, 18.7711) and (19.3076, 18.7711) .. (19.3325, 18.8003).. controls (19.3538, 18.8249) and (19.3752, 18.8494) .. (19.3973, 18.8747).. controls (19.4184, 18.8993) and (19.4396, 18.9238) .. (19.4614, 18.9491).. controls (19.5213, 19.007) and (19.5213, 19.007) .. (19.6007, 19.007).. controls (19.6378, 18.9328) and (19.6305, 18.8713) .. (19.6305, 18.7883).. controls (19.6307, 18.736) and (19.6307, 18.736) .. (19.6308, 18.6826).. controls (19.6308, 18.6443) and (19.6307, 18.606) .. (19.6306, 18.5677).. controls (19.6307, 18.5284) and (19.6307, 18.4892) .. (19.6307, 18.45).. controls (19.6308, 18.3676) and (19.6307, 18.2853) .. (19.6306, 18.2029).. controls (19.6304, 18.0977) and (19.6305, 17.9925) .. (19.6307, 17.8872).. controls (19.6308, 17.8061) and (19.6307, 17.725) .. (19.6307, 17.6439).. controls (19.6306, 17.6052) and (19.6307, 17.5664) .. (19.6307, 17.5276).. controls (19.6308, 17.4732) and (19.6307, 17.4187) .. (19.6305, 17.3643).. controls (19.6305, 17.3179) and (19.6305, 17.3179) .. (19.6305, 17.2706).. controls (19.627, 17.1776) and (19.6154, 17.088) .. (19.6007, 16.9962).. controls (19.5303, 17.0666) and (19.5157, 17.133) .. (19.4849, 17.2277).. controls (19.4791, 17.2454) and (19.4732, 17.2632) .. (19.4672, 17.2815).. controls (19.4297, 17.3966) and (19.3978, 17.5123) .. (19.3675, 17.6295).. controls (19.3066, 17.8478) and (19.2048, 18.0411) .. (19.098, 18.2397).. controls (19.0856, 18.2632) and (19.0732, 18.2868) .. (19.0604, 18.311).. controls (19.0301, 18.3675) and (18.9985, 18.4228) .. (18.9657, 18.4778).. controls (18.9551, 18.4957) and (18.9444, 18.5136) .. (18.9335, 18.532).. controls (18.6836, 18.9289) and (18.3109, 19.3624) .. (17.8809, 19.5626).. controls (17.9371, 19.4456) and (17.9969, 19.3328) .. (18.0632, 19.221).. controls (18.1598, 19.0572) and (18.2375, 18.8954) .. (18.3021, 18.7158).. controls (18.3269, 18.6471) and (18.3544, 18.5811) .. (18.3836, 18.5142).. controls (18.594, 17.9877) and (18.6766, 17.3934) .. (18.6809, 16.8296).. controls (18.6812, 16.8015) and (18.6814, 16.7735) .. (18.6817, 16.7446).. controls (18.6861, 16.1405) and (18.6833, 15.5539) .. (18.5688, 14.9589).. controls (18.5641, 14.933) and (18.5594, 14.9071) .. (18.5546, 14.8804).. controls (18.312, 13.5511) and (17.7228, 12.2625) .. (17.112, 11.0654).. controls (17.0696, 10.9821) and (17.028, 10.8985) .. (16.9863, 10.8148).. controls (16.9687, 10.7798) and (16.9512, 10.7447) .. (16.9336, 10.7096).. controls (16.9198, 10.6819) and (16.9198, 10.6819) .. (16.9057, 10.6537).. controls (16.8049, 10.4521) and (16.8049, 10.4521) .. (16.7677, 10.3778).. controls (16.7424, 10.3272) and (16.7172, 10.2767) .. (16.692, 10.2262).. controls (16.6383, 10.1186) and (16.5845, 10.0112) .. (16.5299, 9.9041).. controls (16.403, 9.6545) and (16.2853, 9.401) .. (16.169, 9.1462).. controls (16.11, 9.0171) and (16.0503, 8.8888) .. (15.9861, 8.7622).. controls (15.9243, 8.6399) and (15.8696, 8.5155) .. (15.8171, 8.3889).. controls (15.808, 8.3672) and (15.7989, 8.3454) .. (15.7895, 8.323).. controls (15.7266, 8.1717) and (15.6667, 8.0195) .. (15.609, 7.8662).. controls (15.5805, 7.7925) and (15.5495, 7.7205) .. (15.5178, 7.6481).. controls (15.4066, 7.3841) and (15.3225, 7.1088) .. (15.235, 6.8362).. controls (15.2262, 6.8087) and (15.2173, 6.7812) .. (15.2082, 6.7529).. controls (15.1416, 6.5418) and (15.0872, 6.329) .. (15.0366, 6.1135).. controls (15.0206, 6.0463) and (15.0046, 5.979) .. (14.9885, 5.9118).. controls (14.9771, 5.8637) and (14.9771, 5.8637) .. (14.9655, 5.8147).. controls (14.9245, 5.6433) and (14.8815, 5.4724) .. (14.8382, 5.3016).. controls (14.7936, 5.2822) and (14.7936, 5.2822) .. (14.7323, 5.2751).. controls (14.5388, 5.3943) and (14.3763, 5.5748) .. (14.2182, 5.7363).. controls (14.1598, 5.7948) and (14.1004, 5.8497) .. (14.0378, 5.9035).. controls (13.8399, 6.0736) and (13.6247, 6.2612) .. (13.5318, 6.5104).. controls (13.5217, 6.7793) and (13.7699, 7.0647) .. (13.9224, 7.2708).. controls (13.9938, 7.3675) and (14.0608, 7.4668) .. (14.1271, 7.5671).. controls (14.1381, 7.5837) and (14.1491, 7.6004) .. (14.1605, 7.6176).. controls (14.1822, 7.6503) and (14.2038, 7.6831) .. (14.2254, 7.7158).. controls (14.2711, 7.785) and (14.3174, 7.8538) .. (14.3636, 7.9226).. controls (15.2934, 9.3182) and (16.0576, 10.8348) .. (16.6109, 12.4189).. controls (16.6192, 12.4428) and (16.6276, 12.4666) .. (16.6362, 12.4912).. controls (17.4248, 14.7647) and (17.6521, 17.2033) .. (16.8755, 19.5097).. controls (16.869, 19.5294) and (16.8625, 19.5491) .. (16.8558, 19.5695).. controls (16.7013, 20.0339) and (16.488, 20.5234) .. (16.1875, 20.912).. controls (16.168, 20.9373) and (16.1484, 20.9627) .. (16.1282, 20.9888).. controls (15.9192, 21.265) and (15.9192, 21.265) .. (15.6319, 21.4412).. controls (15.6468, 21.4041) and (15.6468, 21.4041) .. (15.662, 21.3662).. controls (15.7408, 21.1657) and (15.809, 20.9651) .. (15.8634, 20.7566).. controls (15.8687, 20.7365) and (15.8739, 20.7164) .. (15.8793, 20.6957).. controls (16.1803, 19.5085) and (16.0444, 18.2323) .. (15.6848, 17.0755).. controls (15.6753, 17.0446) and (15.6657, 17.0136) .. (15.6559, 16.9817).. controls (15.5556, 16.6696) and (15.4186, 16.3755) .. (15.2715, 16.0833).. controls (15.2447, 16.0298) and (15.218, 15.9763) .. (15.1914, 15.9227).. controls (15.1742, 15.8884) and (15.157, 15.854) .. (15.1397, 15.8196).. controls (15.1244, 15.7889) and (15.109, 15.7582) .. (15.0932, 15.7266).. controls (15.0565, 15.6591) and (15.0187, 15.6006) .. (14.9705, 15.541).. controls (14.9792, 15.5322) and (14.9879, 15.5235) .. (14.9969, 15.5145).. controls (15.1472, 15.6272) and (15.2543, 15.7622) .. (15.3673, 15.9114).. controls (15.384, 15.9332) and (15.384, 15.9332) .. (15.401, 15.9555).. controls (15.8734, 16.5771) and (16.2425, 17.246) .. (16.4521, 18.0016).. controls (16.487, 18.0016) and (16.522, 18.0016) .. (16.558, 18.0016).. controls (16.619, 17.8518) and (16.6486, 17.7071) .. (16.6661, 17.5467).. controls (16.6683, 17.5259) and (16.6706, 17.5051) .. (16.6729, 17.4837).. controls (16.6961, 17.2545) and (16.6984, 17.0263) .. (16.6969, 16.7961).. controls (16.6968, 16.7742) and (16.6967, 16.7524) .. (16.6966, 16.7299).. controls (16.6924, 15.8716) and (16.5706, 15.0423) .. (16.3827, 14.2065).. controls (16.3775, 14.1836) and (16.3724, 14.1608) .. (16.3671, 14.1372).. controls (16.3523, 14.0715) and (16.3373, 14.0059) .. (16.3221, 13.9403).. controls (16.3177, 13.9211) and (16.3133, 13.9019) .. (16.3088, 13.8821).. controls (16.2808, 13.7626) and (16.2458, 13.6471) .. (16.2056, 13.5312).. controls (16.183, 13.4636) and (16.1649, 13.395) .. (16.147, 13.3261).. controls (15.9196, 12.4547) and (15.5711, 11.5897) .. (15.1292, 10.8049).. controls (15.1016, 10.7542) and (15.074, 10.7035) .. (15.0465, 10.6528).. controls (15.0343, 10.6307) and (15.0222, 10.6087) .. (15.0096, 10.5859).. controls (14.971, 10.5149) and (14.9336, 10.4432) .. (14.8963, 10.3714).. controls (14.783, 10.155) and (14.6566, 9.9495) .. (14.5207, 9.7466).. controls (14.5064, 9.7251) and (14.4921, 9.7035) .. (14.4773, 9.6813).. controls (14.2623, 9.3581) and (14.0383, 9.0454) .. (13.7961, 8.742).. controls (13.7549, 8.6902) and (13.7143, 8.6381) .. (13.6739, 8.5857).. controls (13.5476, 8.4224) and (13.4184, 8.2644) .. (13.2785, 8.1124).. controls (13.2278, 8.0572) and (13.1787, 8.001) .. (13.1299, 7.9441).. controls (12.758, 7.5189) and (12.758, 7.5189) .. (12.5611, 7.4827).. controls (12.3663, 7.5201) and (12.2599, 7.6712) .. (12.1394, 7.8151).. controls (12.1151, 7.8429) and (12.0908, 7.8706) .. (12.0663, 7.8982).. controls (11.3884, 8.6698) and (11.3884, 8.6698) .. (11.3721, 8.9793).. controls (11.4753, 9.0749) and (11.5697, 9.1088) .. (11.7045, 9.1364).. controls (12.1134, 9.2307) and (12.5127, 9.4189) .. (12.8163, 9.7144).. controls (12.8538, 9.7466) and (12.8538, 9.7466) .. (12.9067, 9.7466).. controls (12.9067, 9.7641) and (12.9067, 9.7815) .. (12.9067, 9.7995).. controls (12.9463, 9.8375) and (12.9463, 9.8375) .. (12.9977, 9.8789).. controls (13.0695, 9.9356) and (13.0695, 9.9356) .. (13.1184, 10.0112).. controls (13.1358, 10.0112) and (13.1533, 10.0112) .. (13.1713, 10.0112).. controls (13.1781, 10.0263) and (13.1849, 10.0414) .. (13.1919, 10.057).. controls (13.2275, 10.1232) and (13.2696, 10.1739) .. (13.3185, 10.2311).. controls (13.6357, 10.6229) and (13.8602, 11.0969) .. (14.0253, 11.5706).. controls (14.0446, 11.6257) and (14.0647, 11.6805) .. (14.0848, 11.7353).. controls (14.2021, 12.0621) and (14.2715, 12.3956) .. (14.3355, 12.7364).. controls (14.3414, 12.767) and (14.3414, 12.767) .. (14.3475, 12.7983).. controls (14.3996, 13.0664) and (14.4301, 13.3362) .. (14.4578, 13.6079).. controls (14.4611, 13.6396) and (14.4643, 13.6714) .. (14.4677, 13.7042).. controls (14.5104, 14.1443) and (14.5243, 14.5836) .. (14.5251, 15.0256).. controls (14.5253, 15.1093) and (14.5257, 15.193) .. (14.5262, 15.2766).. controls (14.5276, 15.5142) and (14.5289, 15.7518) .. (14.5293, 15.9894).. controls (14.5312, 16.9445) and (14.5771, 17.8761) .. (14.7574, 18.8154).. controls (14.8501, 19.3279) and (14.8392, 19.8694) .. (14.7588, 20.3828).. controls (14.7539, 20.4166) and (14.7491, 20.4503) .. (14.7441, 20.4851).. controls (14.5999, 21.3705) and (14.1325, 22.4098) .. (13.4265, 22.9919).. controls (13.3874, 23.0249) and (13.3508, 23.0609) .. (13.3146, 23.0972).. controls (12.9804, 23.4303) and (12.3476, 23.9381) .. (11.8748, 24.0076).. controls (11.9082, 23.8985) and (11.9488, 23.8047) .. (12.0065, 23.7064).. controls (12.022, 23.6796) and (12.0374, 23.6528) .. (12.0534, 23.6252).. controls (12.078, 23.5829) and (12.078, 23.5829) .. (12.103, 23.5396).. controls (12.2523, 23.2779) and (12.3828, 23.0161) .. (12.4906, 22.7347).. controls (12.5069, 22.6924) and (12.524, 22.6505) .. (12.5414, 22.6086).. controls (12.6398, 22.3615) and (12.6916, 22.0973) .. (12.748, 21.838).. controls (12.752, 21.8196) and (12.7561, 21.8011) .. (12.7603, 21.7821).. controls (12.9403, 20.941) and (12.9155, 20.0801) .. (12.9091, 19.2256).. controls (12.9072, 18.9709) and (12.9057, 18.7163) .. (12.9048, 18.4617).. controls (12.9043, 18.374) and (12.9036, 18.2863) .. (12.9027, 18.1986).. controls (12.8972, 17.6886) and (12.8972, 17.6886) .. (12.9879, 17.1889).. controls (13.0125, 17.102) and (13.0125, 17.102) .. (13.0125, 16.9962).. controls (13.0475, 16.9962) and (13.0824, 16.9962) .. (13.1184, 16.9962).. controls (13.1536, 17.2298) and (13.1794, 17.4636) .. (13.1994, 17.699).. controls (13.2025, 17.7347) and (13.2025, 17.7347) .. (13.2057, 17.7712).. controls (13.2444, 18.2421) and (13.2551, 18.7135) .. (13.2541, 19.1858).. controls (13.254, 19.2698) and (13.2541, 19.3538) .. (13.2543, 19.4377).. controls (13.2545, 19.934) and (13.244, 20.4301) .. (13.1878, 20.9236).. controls (13.1844, 20.9547) and (13.181, 20.9858) .. (13.1775, 21.0178).. controls (13.1543, 21.2212) and (13.1237, 21.4211) .. (13.08, 21.6211).. controls (13.0643, 21.7125) and (13.063, 21.7984) .. (13.0655, 21.891).. controls (13.0829, 21.8997) and (13.1004, 21.9084) .. (13.1184, 21.9174).. controls (13.5506, 21.5223) and (13.6926, 20.8788) .. (13.8063, 20.3299).. controls (13.811, 20.3084) and (13.8156, 20.2868) .. (13.8205, 20.2647).. controls (13.8692, 20.0237) and (13.8848, 19.7793) .. (13.9022, 19.5345).. controls (13.9039, 19.5103) and (13.9056, 19.486) .. (13.9074, 19.461).. controls (13.9625, 18.6631) and (13.947, 17.872) .. (13.9022, 17.0739).. controls (13.9005, 17.0441) and (13.8989, 17.0144) .. (13.8972, 16.9837).. controls (13.8795, 16.6751) and (13.8577, 16.3682) .. (13.8186, 16.0615).. controls (13.8075, 15.9735) and (13.7979, 15.8856) .. (13.7893, 15.7974).. controls (13.6662, 14.5487) and (13.4971, 13.2669) .. (13.0919, 12.0749).. controls (13.0813, 12.0435) and (13.0813, 12.0435) .. (13.0705, 12.0115).. controls (12.9151, 11.5616) and (12.6834, 11.137) .. (12.404, 10.752).. controls (12.3885, 10.7306) and (12.373, 10.7092) .. (12.357, 10.6871).. controls (12.1261, 10.3845) and (11.8488, 10.1145) .. (11.5309, 9.9053).. controls (11.5076, 9.8891) and (11.4843, 9.8729) .. (11.4603, 9.8561).. controls (11.2695, 9.7273) and (11.026, 9.5714) .. (10.7867, 9.5812).. controls (10.6418, 9.6126) and (10.5075, 9.7085) .. (10.3932, 9.7995).. controls (10.3932, 9.817) and (10.3932, 9.8344) .. (10.3932, 9.8524).. controls (10.3773, 9.859) and (10.3615, 9.8655) .. (10.3452, 9.8723).. controls (10.279, 9.9101) and (10.2482, 9.9469) .. (10.208, 10.0112).. controls (10.208, 10.0286) and (10.208, 10.0461) .. (10.208, 10.0641).. controls (10.1861, 10.0719) and (10.1861, 10.0719) .. (10.1638, 10.0798).. controls (10.0761, 10.1327) and (10.0225, 10.2086) .. (9.9616, 10.289).. controls (9.9488, 10.3055) and (9.9361, 10.3221) .. (9.9229, 10.3391).. controls (9.5795, 10.7872) and (9.5795, 10.7872) .. (9.5614, 10.9091).. controls (9.573, 10.9901) and (9.573, 10.9901) .. (9.629, 11.042).. controls (9.7097, 11.0991) and (9.792, 11.1464) .. (9.8789, 11.1935).. controls (10.1487, 11.3443) and (10.383, 11.5155) .. (10.5784, 11.7574).. controls (10.5992, 11.7794) and (10.5992, 11.7794) .. (10.6204, 11.8019).. controls (12.0703, 13.3371) and (11.8172, 16.1605) .. (11.7631, 18.1193).. controls (11.7306, 19.143) and (11.6123, 20.1657) .. (11.4104, 21.1698).. controls (11.3995, 21.2249) and (11.3891, 21.28) .. (11.3789, 21.3352).. controls (11.334, 21.5739) and (11.2725, 21.8054) .. (11.2052, 22.0384).. controls (11.1864, 22.1044) and (11.1684, 22.1706) .. (11.1505, 22.2369).. controls (10.8857, 23.2092) and (10.4531, 24.4364) .. (9.573, 25.013).. controls (9.5538, 25.0277) and (9.5346, 25.0423) .. (9.5148, 25.0574).. controls (9.347, 25.1823) and (9.1651, 25.2291) .. (8.9644, 25.2776).. controls (8.973, 25.2546) and (8.9817, 25.2315) .. (8.9906, 25.2078).. controls (9.2774, 24.426) and (9.301, 23.6084) .. (9.349, 22.7854).. controls (9.3608, 22.5842) and (9.374, 22.3831) .. (9.3877, 22.182).. controls (9.4139, 22.182) and (9.4401, 22.182) .. (9.4671, 22.182).. controls (9.5077, 22.4007) and (9.5319, 22.6165) .. (9.5456, 22.8384).. controls (9.5498, 22.9019) and (9.5541, 22.9654) .. (9.5584, 23.0288).. controls (9.565, 23.1276) and (9.5714, 23.2265) .. (9.5776, 23.3253).. controls (9.5837, 23.4215) and (9.5902, 23.5177) .. (9.5968, 23.614).. controls (9.5986, 23.6435) and (9.6003, 23.6731) .. (9.6021, 23.7036).. controls (9.604, 23.7311) and (9.606, 23.7587) .. (9.608, 23.7871).. controls (9.6103, 23.8233) and (9.6103, 23.8233) .. (9.6127, 23.8602).. controls (9.6282, 23.9401) and (9.6601, 23.9935) .. (9.7052, 24.0605).. controls (9.8303, 24.0117) and (9.8573, 23.933) .. (9.912, 23.8163).. controls (9.9593, 23.706) and (9.9986, 23.5947) .. (10.0343, 23.4801).. controls (10.0422, 23.455) and (10.0501, 23.4299) .. (10.0582, 23.404).. controls (10.133, 23.1584) and (10.1879, 22.9096) .. (10.2414, 22.6587).. controls (10.2928, 22.4188) and (10.3482, 22.1798) .. (10.4039, 21.9409).. controls (10.4207, 21.8685) and (10.4375, 21.7961) .. (10.4543, 21.7237).. controls (10.5448, 21.3337) and (10.6415, 20.9454) .. (10.7413, 20.5576).. controls (10.9615, 19.7013) and (11.1548, 18.858) .. (11.2328, 17.9751).. controls (11.2373, 17.9248) and (11.2421, 17.8745) .. (11.2473, 17.8243).. controls (11.368, 16.5998) and (11.254, 15.2749) .. (10.843, 14.1122).. controls (10.831, 14.0766) and (10.819, 14.0409) .. (10.807, 14.0052).. controls (10.6689, 13.6055) and (10.4713, 13.2266) .. (10.208, 12.8951).. controls (10.1928, 12.875) and (10.1777, 12.8548) .. (10.1621, 12.834).. controls (9.8871, 12.4702) and (9.5624, 12.1352) .. (9.1761, 11.8897).. controls (9.1593, 11.8783) and (9.1425, 11.8669) .. (9.1251, 11.8551).. controls (9.0165, 11.7855) and (8.9335, 11.7622) .. (8.8057, 11.7839).. controls (8.7101, 11.8837) and (8.6557, 11.9979) .. (8.5973, 12.1212).. controls (8.4292, 12.4648) and (8.2264, 12.7564) .. (7.9061, 12.9745).. controls (7.9061, 12.992) and (7.9061, 13.0094) .. (7.9061, 13.0274).. controls (7.8837, 13.0345) and (7.8613, 13.0416) .. (7.8383, 13.0489).. controls (7.7473, 13.0803) and (7.7473, 13.0803) .. (7.658, 13.1233).. controls (7.5512, 13.1639) and (7.462, 13.1892) .. (7.3505, 13.1597).. controls (7.1796, 13.0483) and (7.0743, 12.8909) .. (6.9701, 12.7198).. controls (6.5545, 12.0599) and (5.9521, 11.3477) .. (5.2073, 11.043).. controls (5.1313, 11.0381) and (5.1313, 11.0381) .. (5.075, 11.043).. controls (5.075, 11.1542) and (5.0786, 11.1669) .. (5.1428, 11.2481).. controls (5.1644, 11.2756) and (5.1644, 11.2756) .. (5.1864, 11.3036).. controls (5.2483, 11.378) and (5.3128, 11.4497) .. (5.3789, 11.5204).. controls (5.5, 11.6768) and (5.4932, 11.8599) .. (5.4719, 12.0485).. controls (5.3115, 13.0164) and (4.9245, 13.9905) .. (4.4665, 14.853).. controls (4.4486, 14.8872) and (4.4486, 14.8872) .. (4.4304, 14.9221).. controls (4.1572, 15.4961) and (4.1572, 15.4961) .. (3.6992, 15.9114).. controls (3.387, 15.9444) and (3.1476, 15.7759) .. (2.911, 15.5883).. controls (2.7833, 15.4779) and (2.6817, 15.3795) .. (2.6144, 15.2235).. controls (2.6144, 15.1885) and (2.6144, 15.1536) .. (2.6144, 15.1176).. controls (2.6324, 15.1174) and (2.6504, 15.1171) .. (2.6689, 15.1169).. controls (2.7516, 15.1154) and (2.8343, 15.1132) .. (2.917, 15.111).. controls (2.9595, 15.1105) and (2.9595, 15.1105) .. (3.0028, 15.1099).. controls (3.2432, 15.1025) and (3.4426, 15.047) .. (3.6228, 14.8819).. controls (3.7848, 14.7024) and (3.9243, 14.4948) .. (4.0362, 14.2808).. controls (4.0619, 14.2325) and (4.0892, 14.185) .. (4.1171, 14.1379).. controls (4.2634, 13.8908) and (4.3817, 13.636) .. (4.493, 13.3714).. controls (4.5041, 13.3449) and (4.5041, 13.3449) .. (4.5155, 13.3179).. controls (4.6964, 12.8855) and (4.8202, 12.4533) .. (4.9163, 11.9955).. controls (4.921, 11.9741) and (4.9258, 11.9527) .. (4.9307, 11.9307).. controls (4.9866, 11.618) and (5.0054, 11.2188) .. (4.8306, 10.9434).. controls (4.8152, 10.9239) and (4.7998, 10.9044) .. (4.784, 10.8843).. controls (4.77, 10.8664) and (4.756, 10.8486) .. (4.7415, 10.8301).. controls (4.5119, 10.5749) and (4.1668, 10.4382) .. (3.8314, 10.4049).. controls (3.7786, 10.408) and (3.7786, 10.408) .. (3.7257, 10.461).. controls (3.7387, 10.6101) and (3.7889, 10.7543) .. (3.8317, 10.8972).. controls (3.9315, 11.2433) and (3.9771, 11.5769) .. (3.9741, 11.9364).. controls (3.9737, 11.9973) and (3.9741, 12.0581) .. (3.9746, 12.119).. controls (3.9754, 12.6218) and (3.8642, 13.0858) .. (3.5873, 13.5105).. controls (3.5405, 13.583) and (3.5405, 13.583) .. (3.5106, 13.6441).. controls (3.4792, 13.7052) and (3.4435, 13.7126) .. (3.3817, 13.7418).. controls (3.3588, 13.7614) and (3.3359, 13.7811) .. (3.3123, 13.8013).. controls (2.8958, 14.1523) and (2.3405, 14.2901) .. (1.8207, 14.4033).. controls (1.7981, 14.4082) and (1.7754, 14.4132) .. (1.7521, 14.4183).. controls (0.9633, 14.584) and (0.1071, 14.5452) .. (-0.6664, 14.3239).. controls (-0.6886, 14.3177) and (-0.7108, 14.3116) .. (-0.7337, 14.3053).. controls (-1.1842, 14.1794) and (-1.6642, 14.0154) .. (-1.9893, 13.6624).. controls (-2.0128, 13.6379) and (-2.0363, 13.6133) .. (-2.0604, 13.588).. controls (-2.1466, 13.4693) and (-2.2132, 13.3428) .. (-2.2804, 13.2126).. controls (-2.2958, 13.1834) and (-2.2958, 13.1834) .. (-2.3115, 13.1536).. controls (-2.477, 12.8322) and (-2.6215, 12.4975) .. (-2.7574, 12.1626).. controls (-2.7813, 12.1055) and (-2.8076, 12.0505) .. (-2.836, 11.9955).. controls (-2.8709, 12.0043) and (-2.9059, 12.013) .. (-2.9418, 12.022).. controls (-2.9775, 12.8634) and (-2.631, 13.7777) .. (-2.0852, 14.4082).. controls (-1.8862, 14.6233) and (-1.6677, 14.7743) .. (-1.4073, 14.906).. controls (-1.372, 14.925) and (-1.372, 14.925) .. (-1.3359, 14.9445).. controls (-0.8845, 15.1828) and (-0.392, 15.3129) .. (0.1009, 15.4351).. controls (0.1223, 15.4405) and (0.1436, 15.4458) .. (0.1657, 15.4513).. controls (0.3828, 15.5045) and (0.6001, 15.5414) .. (0.8219, 15.5693).. controls (1.4813, 15.6529) and (2.0199, 15.7795) .. (2.535, 16.2289).. controls (2.5525, 16.2289) and (2.57, 16.2289) .. (2.588, 16.2289).. controls (2.5949, 16.2447) and (2.6019, 16.2605) .. (2.6091, 16.2767).. controls (2.6421, 16.3369) and (2.6744, 16.3703) .. (2.7252, 16.4157).. controls (3.1178, 16.7994) and (3.3179, 17.411) .. (3.4151, 17.9405).. controls (3.4215, 17.9607) and (3.428, 17.9808) .. (3.4346, 18.0016).. controls (3.514, 18.028) and (3.514, 18.028) .. (3.5934, 18.0016).. controls (3.6418, 17.9349) and (3.6418, 17.9349) .. (3.6942, 17.8478).. controls (3.7036, 17.8323) and (3.7129, 17.8168) .. (3.7225, 17.8009).. controls (3.7957, 17.6775) and (3.8601, 17.5507) .. (3.9227, 17.4217).. controls (3.9674, 17.3329) and (4.0163, 17.2474) .. (4.0663, 17.1615).. controls (4.1729, 16.9781) and (4.2676, 16.7897) .. (4.361, 16.5993).. controls (4.3861, 16.5484) and (4.4116, 16.4976) .. (4.4372, 16.4469).. controls (4.5415, 16.2405) and (4.642, 16.0326) .. (4.741, 15.8237).. controls (4.8426, 15.6096) and (4.9482, 15.3982) .. (5.0612, 15.1898).. controls (5.2174, 14.8998) and (5.347, 14.596) .. (5.4785, 14.2941).. controls (5.4859, 14.2773) and (5.4932, 14.2604) .. (5.5008, 14.2431).. controls (5.667, 13.8605) and (5.8184, 13.4717) .. (5.9496, 13.0756).. controls (5.9731, 13.0055) and (6.0003, 12.9393) .. (6.0308, 12.872).. controls (6.0402, 12.8513) and (6.0495, 12.8306) .. (6.0592, 12.8093).. controls (6.0662, 12.794) and (6.0732, 12.7787) .. (6.0805, 12.7628).. controls (6.1066, 12.7628) and (6.1328, 12.7628) .. (6.1598, 12.7628).. controls (6.1812, 13.1024) and (6.1217, 13.3906) .. (6.0275, 13.7153).. controls (6.021, 13.7383) and (6.0145, 13.7613) .. (6.0078, 13.7849).. controls (5.9303, 14.0581) and (5.8448, 14.3257) .. (5.7365, 14.5885).. controls (5.7259, 14.6147) and (5.7154, 14.6409) .. (5.7045, 14.6678).. controls (5.624, 14.8647) and (5.5356, 15.0574) .. (5.4455, 15.2499).. controls (5.4238, 15.297) and (5.4238, 15.297) .. (5.4016, 15.345).. controls (5.2971, 15.5715) and (5.1874, 15.795) .. (5.075, 16.0176).. controls (5.0496, 16.0682) and (5.0244, 16.1188) .. (4.9993, 16.1696).. controls (4.8082, 16.5554) and (4.614, 16.9407) .. (4.3987, 17.3137).. controls (4.2464, 17.579) and (4.119, 17.8566) .. (3.9902, 18.1339).. controls (3.98, 18.1557) and (3.9698, 18.1775) .. (3.9593, 18.1999).. controls (3.6552, 18.8506) and (3.4255, 19.5787) .. (3.668, 20.2931).. controls (3.6859, 20.3411) and (3.7057, 20.3885) .. (3.7257, 20.4358).. controls (3.7411, 20.4724) and (3.7411, 20.4724) .. (3.7568, 20.5099).. controls (3.8512, 20.7025) and (3.9877, 20.8722) .. (4.1172, 21.0423).. controls (4.3772, 21.3856) and (4.5281, 21.6628) .. (4.493, 22.1026).. controls (4.4116, 22.6537) and (3.8744, 23.0351) .. (3.4611, 23.3462).. controls (3.4352, 23.3657) and (3.4093, 23.3853) .. (3.3826, 23.4055).. controls (3.3583, 23.4236) and (3.334, 23.4416) .. (3.3089, 23.4603).. controls (3.2878, 23.476) and (3.2667, 23.4917) .. (3.2449, 23.5079).. controls (3.1643, 23.5617) and (3.0812, 23.6075) .. (2.9963, 23.6539).. controls (2.8852, 23.7164) and (2.7783, 23.7857) .. (2.6706, 23.8538).. controls (2.4505, 23.9917) and (2.2265, 24.1166) .. (1.9956, 24.2353).. controls (1.8741, 24.2979) and (1.7547, 24.364) .. (1.6355, 24.431).. controls (1.4487, 24.5356) and (1.2603, 24.6366) .. (1.0705, 24.7355).. controls (0.9318, 24.8078) and (0.7951, 24.8826) .. (0.6599, 24.9612).. controls (0.5978, 24.9938) and (0.5978, 24.9938) .. (0.4977, 24.9866).. controls (0.5006, 24.9232) and (0.5006, 24.9232) .. (0.5242, 24.8543).. controls (0.583, 24.8047) and (0.583, 24.8047) .. (0.6596, 24.7657).. controls (0.7022, 24.7419) and (0.7022, 24.7419) .. (0.7457, 24.7177).. controls (0.7763, 24.7011) and (0.8069, 24.6845) .. (0.8384, 24.6674).. controls (0.9015, 24.6324) and (0.9644, 24.597) .. (1.0273, 24.5616).. controls (1.0431, 24.5528) and (1.0588, 24.544) .. (1.075, 24.535).. controls (1.2171, 24.4554) and (1.3558, 24.3711) .. (1.4932, 24.2838).. controls (1.5127, 24.2715) and (1.5323, 24.2593) .. (1.5523, 24.2466).. controls (2.2859, 23.7792) and (2.8712, 23.152) .. (3.0832, 22.2899).. controls (3.1596, 21.9101) and (3.1046, 21.5413) .. (2.8966, 21.2149).. controls (2.6089, 20.7916) and (2.6089, 20.7916) .. (2.3631, 20.7301).. controls (2.3303, 20.7285) and (2.3303, 20.7285) .. (2.2969, 20.7268).. controls (2.3076, 20.8599) and (2.3343, 20.971) .. (2.3779, 21.0972).. controls (2.5684, 21.7482) and (2.3756, 22.4246) .. (2.0692, 23.003).. controls (1.9709, 23.1738) and (1.8544, 23.3389) .. (1.7148, 23.4785).. controls (1.6799, 23.4785) and (1.645, 23.4785) .. (1.609, 23.4785).. controls (1.5802, 23.2305) and (1.7161, 23.0008) .. (1.819, 22.7823).. controls (2.0574, 22.2723) and (2.2002, 21.7672) .. (2.0588, 21.203).. controls (1.9832, 20.9967) and (1.882, 20.8148) .. (1.6884, 20.7003).. controls (1.6225, 20.6799) and (1.5729, 20.6753) .. (1.5032, 20.6739).. controls (1.5013, 20.7927) and (1.5019, 20.9069) .. (1.5161, 21.0249).. controls (1.6052, 21.7946) and (1.4133, 22.5538) .. (1.0272, 23.22).. controls (0.9883, 23.2881) and (0.9525, 23.3577) .. (0.9161, 23.4272).. controls (0.848, 23.5506) and (0.772, 23.6604) .. (0.683, 23.7695).. controls (0.6725, 23.7825) and (0.6621, 23.7956) .. (0.6514, 23.809).. controls (0.5014, 23.9964) and (0.3542, 24.1626) .. (0.1538, 24.2987).. controls (0.1625, 24.255) and (0.1713, 24.2114) .. (0.1802, 24.1664).. controls (0.1977, 24.1664) and (0.2152, 24.1664) .. (0.2332, 24.1664).. controls (0.2757, 24.1155) and (0.3142, 24.065) .. (0.3522, 24.0109).. controls (0.3638, 23.9945) and (0.3755, 23.978) .. (0.3874, 23.9611).. controls (0.9778, 23.1065) and (1.2797, 22.0024) .. (1.1063, 20.9649).. controls (1.0176, 20.5769) and (1.0176, 20.5769) .. (0.9211, 20.5151).. controls (0.852, 20.5183) and (0.8227, 20.5348) .. (0.7718, 20.5814).. controls (0.622, 20.773) and (0.5205, 20.9836) .. (0.4184, 21.203).. controls (0.4063, 21.2286) and (0.4063, 21.2286) .. (0.394, 21.2546).. controls (0.1535, 21.7661) and (0.0085, 22.3104) .. (-0.1341, 22.8554).. controls (-0.2313, 23.2733) and (-0.2313, 23.2733) .. (-0.4018, 23.6637).. controls (-0.428, 23.6724) and (-0.4542, 23.6811) .. (-0.4812, 23.6901).. controls (-0.4952, 23.2432) and (-0.4668, 22.8308) .. (-0.3754, 22.3937).. controls (-0.3641, 22.3373) and (-0.3529, 22.2809) .. (-0.3417, 22.2245).. controls (-0.3248, 22.1392) and (-0.3078, 22.0539) .. (-0.2904, 21.9688).. controls (-0.2616, 21.8274) and (-0.2345, 21.686) .. (-0.211, 21.5436).. controls (-0.1426, 21.1301) and (-0.0084, 20.7433) .. (0.2332, 20.3977).. controls (0.2892, 20.3091) and (0.3106, 20.2369) .. (0.3033, 20.1316).. controls (0.2685, 19.998) and (0.1891, 19.8892) .. (0.1119, 19.7763).. controls (0.0689, 19.7132) and (0.0266, 19.6496) .. (-0.0156, 19.586).. controls (-0.2664, 19.2084) and (-0.2664, 19.2084) .. (-0.3508, 19.0868).. controls (-0.5871, 18.7374) and (-0.7502, 18.3324) .. (-0.9031, 17.9408).. controls (-1.08, 17.489) and (-1.2788, 17.0487) .. (-1.512, 16.6232).. controls (-1.5354, 16.5803) and (-1.5583, 16.5372) .. (-1.5811, 16.494).. controls (-1.7771, 16.1239) and (-2.0025, 15.7699) .. (-2.2539, 15.4351).. controls (-2.2822, 15.3973) and (-2.2822, 15.3973) .. (-2.3111, 15.3588).. controls (-2.3352, 15.3311) and (-2.3352, 15.3311) .. (-2.3598, 15.3028).. controls (-2.3772, 15.3028) and (-2.3947, 15.3028) .. (-2.4127, 15.3028).. controls (-2.3957, 15.4369) and (-2.337, 15.5483) .. (-2.2787, 15.6683).. controls (-2.2681, 15.6904) and (-2.2575, 15.7126) .. (-2.2466, 15.7354).. controls (-2.1776, 15.8785) and (-2.107, 16.0208) .. (-2.0356, 16.1627).. controls (-1.856, 16.5202) and (-1.7147, 16.8852) .. (-1.578, 17.2607).. controls (-1.5594, 17.3116) and (-1.5408, 17.3626) .. (-1.5222, 17.4135).. controls (-1.5095, 17.4485) and (-1.4967, 17.4835) .. (-1.484, 17.5184).. controls (-1.4076, 17.728) and (-1.3286, 17.936) .. (-1.2435, 18.1421).. controls (-0.7034, 19.4641) and (-0.7431, 20.6485) .. (-1.1691, 21.9968).. controls (-1.1928, 22.0523) and (-1.2187, 22.103) .. (-1.2485, 22.1555).. controls (-1.2841, 22.0844) and (-1.2811, 22.0257) .. (-1.2844, 21.946).. controls (-1.2865, 21.8965) and (-1.2865, 21.8965) .. (-1.2887, 21.846).. controls (-1.2894, 21.8283) and (-1.2901, 21.8105) .. (-1.2908, 21.7922).. controls (-1.2931, 21.7362) and (-1.2955, 21.6801) .. (-1.2979, 21.624).. controls (-1.3039, 21.4842) and (-1.3097, 21.3444) .. (-1.3154, 21.2046).. controls (-1.3673, 19.946) and (-1.3673, 19.946) .. (-1.4569, 19.4006).. controls (-1.4636, 19.358) and (-1.4636, 19.358) .. (-1.4705, 19.3146).. controls (-1.5318, 18.936) and (-1.5964, 18.5568) .. (-1.6983, 18.1868).. controls (-1.703, 18.169) and (-1.7077, 18.1512) .. (-1.7125, 18.1329).. controls (-1.8791, 17.5008) and (-2.1099, 16.8853) .. (-2.3598, 16.2818).. controls (-2.3763, 16.2415) and (-2.3928, 16.2012) .. (-2.4093, 16.1609).. controls (-2.4463, 16.0705) and (-2.4835, 15.9801) .. (-2.5209, 15.8899).. controls (-2.5381, 15.8484) and (-2.5553, 15.8069) .. (-2.5724, 15.7654).. controls (-2.6657, 15.5396) and (-2.7634, 15.3157) .. (-2.8613, 15.0919).. controls (-2.9114, 14.9775) and (-2.9612, 14.8631) .. (-3.0111, 14.7487).. controls (-3.031, 14.7031) and (-3.0508, 14.6575) .. (-3.0707, 14.6119).. controls (-3.0802, 14.5901) and (-3.0897, 14.5683) .. (-3.0995, 14.5458).. controls (-3.1251, 14.4871) and (-3.1507, 14.4284) .. (-3.1764, 14.3697).. controls (-3.3187, 14.0437) and (-3.4582, 13.7188) .. (-3.5724, 13.3817).. controls (-3.6782, 13.0745) and (-3.6782, 13.0745) .. (-3.7885, 13.001).. controls (-3.8147, 13.001) and (-3.8409, 13.001) .. (-3.8679, 13.001).. controls (-3.8344, 13.3762) and (-3.7514, 13.7302) .. (-3.6298, 14.0858).. controls (-3.6236, 14.1037) and (-3.6175, 14.1215) .. (-3.6112, 14.14).. controls (-3.4904, 14.4916) and (-3.3616, 14.8408) .. (-3.2285, 15.188).. controls (-3.084, 15.5663) and (-2.9545, 15.9475) .. (-2.836, 16.3347).. controls (-2.828, 16.3606) and (-2.82, 16.3865) .. (-2.8118, 16.4132).. controls (-2.7148, 16.7303) and (-2.6286, 17.0494) .. (-2.5499, 17.3715).. controls (-2.5384, 17.4184) and (-2.5384, 17.4184) .. (-2.5267, 17.4662).. controls (-2.4846, 17.6422) and (-2.4511, 17.8173) .. (-2.4252, 17.9963).. controls (-2.4128, 18.0798) and (-2.3988, 18.1629) .. (-2.3841, 18.2461).. controls (-2.3792, 18.2743) and (-2.3742, 18.3025) .. (-2.3691, 18.3315).. controls (-2.3612, 18.3761) and (-2.3612, 18.3761) .. (-2.3531, 18.4216).. controls (-2.3064, 18.688) and (-2.2638, 18.9548) .. (-2.2238, 19.2223).. controls (-2.0194, 20.5908) and (-2.0194, 20.5908) .. (-1.8323, 21.2141).. controls (-1.8041, 21.3091) and (-1.7792, 21.4043) .. (-1.7562, 21.5007).. controls (-1.75, 21.5265) and (-1.7438, 21.5523) .. (-1.7375, 21.5788).. controls (-1.7239, 21.6577) and (-1.7225, 21.7317) .. (-1.7248, 21.8116).. controls (-2.0479, 21.3494) and (-2.1314, 20.7162) .. (-2.2275, 20.1712).. controls (-2.3443, 19.513) and (-2.4733, 18.8565) .. (-2.6616, 18.2144).. controls (-2.684, 18.1369) and (-2.7054, 18.0591) .. (-2.7267, 17.9812).. controls (-3.094, 16.6455) and (-3.5442, 15.3318) .. (-4.1077, 14.0659).. controls (-4.1281, 14.0196) and (-4.1281, 14.0196) .. (-4.149, 13.9724).. controls (-4.2194, 13.8141) and (-4.292, 13.658) .. (-4.3706, 13.5037).. controls (-4.4666, 13.3044) and (-4.5535, 13.1034) .. (-4.6312, 12.8964).. controls (-4.658, 12.8255) and (-4.6859, 12.7553) .. (-4.7145, 12.6851).. controls (-4.8855, 12.2862) and (-4.8855, 12.2862) .. (-4.9527, 11.8633).. controls (-4.8372, 11.9275) and (-4.7399, 12.0061) .. (-4.6385, 12.0898).. controls (-3.9488, 12.6488) and (-3.9488, 12.6488) .. (-3.6215, 12.6735).. controls (-3.4931, 12.6518) and (-3.4536, 12.6195) .. (-3.3652, 12.5247).. controls (-3.2999, 12.4013) and (-3.2943, 12.2687) .. (-3.2809, 12.1321).. controls (-3.2783, 12.1067) and (-3.2756, 12.0814) .. (-3.2728, 12.0552).. controls (-3.2615, 11.9472) and (-3.2505, 11.8392) .. (-3.2396, 11.7312).. controls (-3.2061, 11.2741) and (-3.2061, 11.2741) .. (-3.1006, 10.8314).. controls (-3.0744, 10.8226) and (-3.0482, 10.8139) .. (-3.0212, 10.8049).. controls (-2.954, 10.8718) and (-2.8873, 10.9389) .. (-2.8216, 11.0073).. controls (-2.4422, 11.3985) and (-2.041, 11.6219) .. (-1.4902, 11.6312).. controls (-1.2272, 11.6119) and (-0.986, 11.5226) .. (-0.7391, 11.4355).. controls (-0.5363, 11.3656) and (-0.356, 11.3306) .. (-0.1406, 11.3291).. controls (-0.1038, 11.3286) and (-0.1038, 11.3286) .. (-0.0664, 11.328).. controls (0.1343, 11.3419) and (0.3158, 11.3948) .. (0.5045, 11.4616).. controls (0.5342, 11.4721) and (0.5342, 11.4721) .. (0.5646, 11.4828).. controls (0.6473, 11.5121) and (0.7299, 11.5414) .. (0.8122, 11.5718).. controls (1.1388, 11.6917) and (1.4976, 11.7949) .. (1.8355, 11.6532).. controls (2.1299, 11.4763) and (2.2675, 11.1929) .. (2.3529, 10.8739).. controls (2.4952, 10.2927) and (2.4547, 9.7198) .. (2.1646, 9.191).. controls (2.0469, 9.0048) and (1.8973, 8.8628) .. (1.7148, 8.7412).. controls (1.6437, 8.7511) and (1.6437, 8.7511) .. (1.5825, 8.7676).. controls (1.5883, 8.7967) and (1.594, 8.8258) .. (1.5999, 8.8558).. controls (1.6877, 9.3155) and (1.6826, 9.6779) .. (1.4569, 10.0972).. controls (1.3655, 10.2088) and (1.2685, 10.2862) .. (1.1243, 10.3141).. controls (0.9052, 10.3243) and (0.7115, 10.2375) .. (0.5104, 10.1608).. controls (0.327, 10.0924) and (0.1646, 10.0421) .. (-0.0314, 10.0376).. controls (-0.0636, 10.0361) and (-0.0636, 10.0361) .. (-0.0965, 10.0345).. controls (-0.4536, 10.0249) and (-0.7964, 10.0929) .. (-1.1418, 10.1745).. controls (-1.5242, 10.2639) and (-2.0073, 10.3712) .. (-2.3862, 10.2228).. controls (-2.454, 10.1778) and (-2.5152, 10.1299) .. (-2.5764, 10.0763).. controls (-2.6243, 10.0376) and (-2.6243, 10.0376) .. (-2.6773, 10.0376).. controls (-2.6849, 10.0174) and (-2.6925, 9.9972) .. (-2.7004, 9.9764).. controls (-2.7302, 9.9053) and (-2.7302, 9.9053) .. (-2.7831, 9.826).. controls (-2.8061, 9.6387) and (-2.7537, 9.5063) .. (-2.6508, 9.3497).. controls (-2.5202, 9.2026) and (-2.3449, 9.1342) .. (-2.1564, 9.0951).. controls (-2.112, 9.0855) and (-2.112, 9.0855) .. (-2.0667, 9.0758).. controls (-1.7821, 9.0288) and (-1.4985, 9.0273) .. (-1.2108, 9.0273).. controls (-1.1393, 9.0273) and (-1.0679, 9.0268) .. (-0.9964, 9.0263).. controls (-0.9503, 9.0262) and (-0.9042, 9.0261) .. (-0.858, 9.0261).. controls (-0.837, 9.0259) and (-0.816, 9.0257) .. (-0.7944, 9.0255).. controls (-0.4017, 9.0271) and (-0.0799, 9.1949) .. (0.2442, 9.4024).. controls (0.4749, 9.5488) and (0.6685, 9.649) .. (0.9475, 9.6143).. controls (1.1315, 9.5693) and (1.2432, 9.4488) .. (1.3395, 9.2918).. controls (1.453, 9.0514) and (1.4302, 8.7396) .. (1.356, 8.4898).. controls (1.2655, 8.2604) and (1.1102, 8.0243) .. (0.8946, 7.8945).. controls (0.8684, 7.9032) and (0.8422, 7.912) .. (0.8152, 7.921).. controls (0.8178, 7.9402) and (0.8203, 7.9594) .. (0.8229, 7.9793).. controls (0.8519, 8.2427) and (0.8522, 8.5058) .. (0.6923, 8.7294).. controls (0.6558, 8.7724) and (0.6558, 8.7724) .. (0.592, 8.8024).. controls (0.4894, 8.7898) and (0.4306, 8.7375) .. (0.3655, 8.6618).. controls (0.2845, 8.5402) and (0.2427, 8.4398) .. (0.2596, 8.2914).. controls (0.3083, 8.2207) and (0.3638, 8.1624) .. (0.4224, 8.0998).. controls (0.4848, 8.0067) and (0.5054, 7.9255) .. (0.4977, 7.8151).. controls (0.474, 7.7327) and (0.4384, 7.6586) .. (0.4002, 7.582).. controls (0.3804, 7.5396) and (0.3606, 7.4972) .. (0.3409, 7.4548).. controls (0.3313, 7.4347) and (0.3218, 7.4145) .. (0.3119, 7.3938).. controls (0.0997, 6.9432) and (0.09, 6.4757) .. (0.1061, 5.9872).. controls (0.1156, 5.6175) and (0.0274, 5.3356) .. (-0.1902, 5.037).. controls (-0.2015, 5.0205) and (-0.2127, 5.0041) .. (-0.2244, 4.9871).. controls (-0.4335, 4.7111) and (-0.7845, 4.5449) .. (-1.0898, 4.402).. controls (-1.3093, 4.2962) and (-1.5192, 4.1847) .. (-1.7238, 4.0527).. controls (-2.2356, 3.7497) and (-2.9711, 3.8431) .. (-3.5257, 3.9764).. controls (-3.7812, 4.0492) and (-3.9355, 4.1302) .. (-4.0895, 4.3491).. controls (-4.2852, 4.6193) and (-4.5275, 4.6561) .. (-4.8375, 4.7206).. controls (-5.1966, 4.7971) and (-5.4718, 4.9519) .. (-5.6935, 5.2487).. controls (-5.7782, 5.3816) and (-5.8244, 5.5037) .. (-5.8638, 5.6555).. controls (-5.9574, 5.9868) and (-6.0756, 6.1502) .. (-6.355, 6.3599).. controls (-6.5644, 6.519) and (-6.6929, 6.7326) .. (-6.8357, 6.9494).. controls (-6.9206, 7.0779) and (-7.0102, 7.2019) .. (-7.104, 7.324).. controls (-7.2016, 7.4719) and (-7.2428, 7.6075) .. (-7.2413, 7.7837).. controls (-7.2413, 7.8127) and (-7.2413, 7.8127) .. (-7.2413, 7.8422).. controls (-7.2367, 8.0148) and (-7.1942, 8.1679) .. (-7.1432, 8.3317).. controls (-7.0812, 8.5366) and (-7.0763, 8.7276) .. (-7.1108, 8.939).. controls (-7.155, 9.2981) and (-6.9501, 9.5809) .. (-6.7657, 9.8687).. controls (-6.549, 10.2078) and (-6.3522, 10.5526) .. (-6.2132, 10.9313).. controls (-6.2051, 10.9532) and (-6.1971, 10.975) .. (-6.1888, 10.9975).. controls (-6.1127, 11.2077) and (-6.0494, 11.4209) .. (-5.9868, 11.6354).. controls (-5.8001, 12.2716) and (-5.543, 12.8597) .. (-5.2437, 13.4508).. controls (-5.2346, 13.4688) and (-5.2254, 13.4869) .. (-5.216, 13.5055).. controls (-5.1974, 13.5422) and (-5.1788, 13.579) .. (-5.1602, 13.6158).. controls (-4.8918, 14.1458) and (-4.6348, 14.679) .. (-4.397, 15.2235).. controls (-4.3765, 15.2702) and (-4.3765, 15.2702) .. (-4.3556, 15.318).. controls (-4.0102, 16.0012) and (-4.0102, 16.0012) .. (-3.9338, 16.7371).. controls (-3.9496, 16.8237) and (-3.952, 16.9064) .. (-3.9538, 16.9944).. controls (-3.9546, 17.0308) and (-3.9554, 17.0671) .. (-3.9563, 17.1035).. controls (-3.9567, 17.1224) and (-3.9571, 17.1413) .. (-3.9575, 17.1608).. controls (-3.9755, 17.961) and (-4.0422, 18.7662) .. (-4.2978, 19.5296).. controls (-4.4066, 19.8813) and (-4.3228, 20.1471) .. (-4.1556, 20.4648).. controls (-4.0549, 20.6509) and (-3.9482, 20.8267) .. (-3.815, 20.9914).. controls (-3.7847, 21.0308) and (-3.7545, 21.0701) .. (-3.7244, 21.1096).. controls (-3.5528, 21.3342) and (-3.3793, 21.5576) .. (-3.2015, 21.7773).. controls (-3.15, 21.8407) and (-3.15, 21.8407) .. (-3.0973, 21.924).. controls (-3.0477, 21.9968) and (-3.0477, 21.9968) .. (-2.9948, 22.0233).. controls (-3.0062, 22.0683) and (-3.0062, 22.0683) .. (-3.0179, 22.1142).. controls (-3.0328, 22.2419) and (-2.9897, 22.3009) .. (-2.9151, 22.4011).. controls (-2.8636, 22.4715) and (-2.8181, 22.5435) .. (-2.7727, 22.6179).. controls (-2.5177, 23.0363) and (-2.2333, 23.4236) .. (-1.9009, 23.7838).. controls (-1.8837, 23.8025) and (-1.8665, 23.8213) .. (-1.8488, 23.8406).. controls (-1.8341, 23.856) and (-1.8195, 23.8714) .. (-1.8044, 23.8872).. controls (-1.7956, 23.9008) and (-1.7868, 23.9143) .. (-1.7777, 23.9283).. controls (-1.7971, 24.0156) and (-1.7971, 24.0156) .. (-1.8859, 24.0554).. controls (-1.9222, 24.0733) and (-1.9586, 24.0908) .. (-1.9951, 24.1082).. controls (-2.0145, 24.1177) and (-2.0339, 24.1272) .. (-2.0538, 24.137).. controls (-2.116, 24.1674) and (-2.1783, 24.1975) .. (-2.2407, 24.2276).. controls (-2.74, 24.4691) and (-2.74, 24.4691) .. (-2.9418, 24.6162).. controls (-2.9665, 24.6326) and (-2.9912, 24.649) .. (-3.0167, 24.6659).. controls (-3.3022, 24.8643) and (-3.5378, 25.0991) .. (-3.7294, 25.3891).. controls (-3.7498, 25.42) and (-3.7498, 25.42) .. (-3.7706, 25.4514).. controls (-3.9203, 25.6817) and (-4.0444, 25.9236) .. (-4.1672, 26.1689).. controls (-4.1896, 26.2131) and (-4.2121, 26.2573) .. (-4.2346, 26.3015).. controls (-4.4193, 26.6652) and (-4.6009, 27.0273) .. (-4.7327, 27.4141).. controls (-4.7429, 27.4438) and (-4.753, 27.4734) .. (-4.7634, 27.504).. controls (-4.9212, 27.9766) and (-4.9883, 28.4609) .. (-5.044, 28.9547).. controls (-5.064, 29.1186) and (-5.0976, 29.2677) .. (-5.1528, 29.4233).. controls (-5.2311, 29.6465) and (-5.2902, 29.8672) .. (-5.1908, 30.093).. controls (-5.1012, 30.2057) and (-5.0103, 30.2614) .. (-4.8733, 30.3047).. controls (-4.6102, 30.2993) and (-4.4086, 30.0462) .. (-4.2312, 29.877).. controls (-4.0441, 29.7018) and (-3.8382, 29.5586) .. (-3.6275, 29.4137).. controls (-3.5648, 29.3704) and (-3.5031, 29.3257) .. (-3.4412, 29.2811).. controls (-3.3331, 29.2056) and (-3.2216, 29.1362) .. (-3.1089, 29.0678).. controls (-3.0925, 29.0578) and (-3.0761, 29.0478) .. (-3.0593, 29.0375).. controls (-2.9526, 28.9738) and (-2.8453, 28.9227) .. (-2.7302, 28.876).. controls (-2.7302, 28.8585) and (-2.7302, 28.841) .. (-2.7302, 28.823).. controls (-2.2728, 28.6608) and (-2.2728, 28.6608) .. (-1.801, 28.716).. controls (-1.7385, 28.7507) and (-1.7274, 28.7857) .. (-1.6983, 28.8495).. controls (-1.7422, 28.8501) and (-1.7422, 28.8501) .. (-1.7869, 28.8507).. controls (-1.8953, 28.8522) and (-2.0038, 28.8543) .. (-2.1122, 28.8564).. controls (-2.1591, 28.8573) and (-2.2061, 28.8581) .. (-2.253, 28.8587).. controls (-2.3205, 28.8596) and (-2.3879, 28.8609) .. (-2.4554, 28.8624).. controls (-2.4764, 28.8626) and (-2.4974, 28.8628) .. (-2.519, 28.8629).. controls (-2.664, 28.8668) and (-2.664, 28.8668) .. (-2.7306, 28.9127).. controls (-2.7566, 28.9553) and (-2.7566, 28.9553) .. (-2.7599, 29.0165).. controls (-2.6995, 29.161) and (-2.5684, 29.2402) .. (-2.4309, 29.3059).. controls (-2.1305, 29.4279) and (-1.8295, 29.4202) .. (-1.5131, 29.3787).. controls (-1.517, 29.5068) and (-1.5816, 29.564) .. (-1.6683, 29.6483).. controls (-1.7638, 29.7293) and (-1.871, 29.7862) .. (-1.9811, 29.845).. controls (-2.2579, 29.9935) and (-2.2579, 29.9935) .. (-2.3333, 30.1195).. controls (-2.3316, 30.2038) and (-2.3316, 30.2038) .. (-2.3068, 30.2783).. controls (-2.1763, 30.3653) and (-2.0361, 30.3446) .. (-1.8835, 30.3312).. controls (-1.6756, 30.286) and (-1.481, 30.2045) .. (-1.2872, 30.1183).. controls (-1.2213, 30.0883) and (-1.2213, 30.0883) .. (-1.1427, 30.093).. controls (-1.128, 30.3741) and (-1.2641, 30.6273) .. (-1.4465, 30.8348).. controls (-1.5119, 30.9196) and (-1.5401, 30.9915) .. (-1.5379, 31.0985).. controls (-1.4969, 31.2297) and (-1.403, 31.3018) .. (-1.2855, 31.3666).. controls (-1.2502, 31.3845) and (-1.2147, 31.4021) .. (-1.179, 31.4193).. controls (-1.1603, 31.4284) and (-1.1416, 31.4376) .. (-1.1222, 31.447).. controls (-0.7376, 31.6298) and (-0.365, 31.6826) .. (0.0, 31.4325) -- cycle;

  \path[fill=cfefefe,shift={(14.314, -6.2706)}] (0.0, 31.4325).. controls (0.6926, 31.2194) and (1.1354, 30.7245) .. (1.4767, 30.1014).. controls (1.6588, 29.7498) and (1.7967, 29.3789) .. (1.905, 28.9983).. controls (1.9117, 28.9765) and (1.9184, 28.9546) .. (1.9253, 28.9321).. controls (2.048, 28.515) and (2.1013, 28.0823) .. (2.1564, 27.6523).. controls (2.2904, 26.5402) and (2.2904, 26.5402) .. (2.7951, 25.5599).. controls (3.4215, 24.7135) and (3.7723, 23.5423) .. (3.7932, 22.4932).. controls (3.7814, 22.4242) and (3.7576, 22.4008) .. (3.7042, 22.3573).. controls (3.6005, 22.4526) and (3.5284, 22.5497) .. (3.4627, 22.6748).. controls (3.4477, 22.7032) and (3.4477, 22.7032) .. (3.4324, 22.7322).. controls (3.3124, 22.9688) and (3.2245, 23.2184) .. (3.1325, 23.4668).. controls (2.9845, 23.8661) and (2.8168, 24.2552) .. (2.6202, 24.633).. controls (2.5912, 24.689) and (2.5627, 24.7452) .. (2.5342, 24.8015).. controls (2.4202, 25.0245) and (2.2979, 25.2286) .. (2.1431, 25.4265).. controls (2.1267, 25.4491) and (2.1103, 25.4718) .. (2.0934, 25.4952).. controls (2.0776, 25.5167) and (2.0618, 25.5382) .. (2.0456, 25.5604).. controls (2.0318, 25.5793) and (2.0181, 25.5981) .. (2.0039, 25.6176).. controls (1.9493, 25.6734) and (1.8992, 25.6933) .. (1.8256, 25.7175).. controls (1.9111, 25.2781) and (2.0126, 24.8422) .. (2.1332, 24.4111).. controls (2.1405, 24.3849) and (2.1478, 24.3587) .. (2.1554, 24.3317).. controls (2.2305, 24.0681) and (2.3162, 23.8083) .. (2.416, 23.5529).. controls (2.4239, 23.5325) and (2.4318, 23.5121) .. (2.44, 23.4911).. controls (2.4961, 23.3494) and (2.5578, 23.2118) .. (2.6237, 23.0743).. controls (2.7475, 22.8135) and (2.8542, 22.5451) .. (2.9633, 22.2779).. controls (2.9724, 22.2561) and (2.9814, 22.2343) .. (2.9907, 22.2118).. controls (3.1575, 21.8074) and (3.2811, 21.3937) .. (3.3685, 20.9649).. controls (3.3727, 20.9443) and (3.3769, 20.9236) .. (3.3813, 20.9024).. controls (3.5189, 20.1872) and (3.5242, 19.294) .. (3.1315, 18.6522).. controls (2.9376, 18.3711) and (2.9376, 18.3711) .. (2.831, 18.3356).. controls (2.8136, 18.3444) and (2.7961, 18.3531) .. (2.7781, 18.3621).. controls (2.7784, 18.3852) and (2.7787, 18.4083) .. (2.779, 18.4321).. controls (2.7885, 19.3512) and (2.7434, 20.2459) .. (2.5135, 21.1402).. controls (2.5073, 21.1648) and (2.5011, 21.1893) .. (2.4947, 21.2146).. controls (2.4741, 21.2957) and (2.4534, 21.3767) .. (2.4325, 21.4577).. controls (2.426, 21.483) and (2.4195, 21.5083) .. (2.4128, 21.5344).. controls (2.3782, 21.6671) and (2.3401, 21.7975) .. (2.2957, 21.9273).. controls (2.2742, 21.9906) and (2.2538, 22.0542) .. (2.2337, 22.1179).. controls (2.2265, 22.1406) and (2.2194, 22.1632) .. (2.212, 22.1865).. controls (2.2045, 22.2101) and (2.1971, 22.2337) .. (2.1894, 22.2581).. controls (2.134, 22.4336) and (2.0772, 22.6084) .. (2.0178, 22.7827).. controls (1.941, 23.0082) and (1.8725, 23.2339) .. (1.815, 23.4652).. controls (1.8101, 23.4846) and (1.8053, 23.504) .. (1.8003, 23.5239).. controls (1.7962, 23.5408) and (1.7921, 23.5576) .. (1.7879, 23.5749).. controls (1.7729, 23.6299) and (1.7729, 23.6299) .. (1.7467, 23.691).. controls (1.7192, 23.7612) and (1.7012, 23.829) .. (1.6845, 23.9025).. controls (1.6782, 23.9302) and (1.6719, 23.9578) .. (1.6654, 23.9863).. controls (1.6588, 24.0157) and (1.6522, 24.0451) .. (1.6454, 24.0754).. controls (1.635, 24.1212) and (1.635, 24.1212) .. (1.6244, 24.1678).. controls (1.6101, 24.2306) and (1.5959, 24.2934) .. (1.5817, 24.3562).. controls (1.5626, 24.4406) and (1.5434, 24.5249) .. (1.524, 24.6092).. controls (1.5183, 24.6342) and (1.5126, 24.6592) .. (1.5067, 24.6849).. controls (1.4956, 24.7338) and (1.4844, 24.7827) .. (1.4731, 24.8316).. controls (1.4443, 24.9579) and (1.4182, 25.0842) .. (1.394, 25.2115).. controls (1.2585, 25.84) and (0.9836, 26.6325) .. (0.4498, 27.0404).. controls (0.377, 27.0676) and (0.377, 27.0676) .. (0.3175, 27.0669).. controls (0.333, 26.845) and (0.432, 26.6454) .. (0.5156, 26.4418).. controls (0.6343, 26.1459) and (0.7029, 25.8439) .. (0.7673, 25.5323).. controls (0.7747, 25.4976) and (0.782, 25.463) .. (0.7894, 25.4283).. controls (0.8292, 25.236) and (0.863, 25.0429) .. (0.8963, 24.8493).. controls (1.0626, 23.8876) and (1.279, 22.9649) .. (1.6669, 22.0663).. controls (1.6745, 22.0485) and (1.6821, 22.0308) .. (1.6899, 22.0125).. controls (1.8005, 21.7545) and (1.9179, 21.5) .. (2.0373, 21.246).. controls (2.1352, 21.0377) and (2.2221, 20.827) .. (2.3019, 20.611).. controls (2.3107, 20.5879) and (2.3196, 20.5648) .. (2.3287, 20.541).. controls (2.3687, 20.4317) and (2.3955, 20.3554) .. (2.3548, 20.2406).. controls (2.3373, 20.2406) and (2.3199, 20.2406) .. (2.3019, 20.2406).. controls (2.2613, 20.2915) and (2.2252, 20.3419) .. (2.1894, 20.3961).. controls (2.178, 20.4133) and (2.1666, 20.4305) .. (2.1548, 20.4483).. controls (1.99, 20.7035) and (1.8516, 20.9743) .. (1.7103, 21.2429).. controls (1.6718, 21.3161) and (1.6329, 21.3891) .. (1.5937, 21.4619).. controls (1.2546, 22.0951) and (0.9523, 22.7497) .. (0.7123, 23.4269).. controls (0.6855, 23.5018) and (0.6579, 23.5764) .. (0.6301, 23.651).. controls (0.3557, 24.3932) and (0.0985, 25.1509) .. (0.2055, 25.9527).. controls (0.2489, 26.3477) and (0.2447, 26.815) .. (0.0, 27.1463).. controls (-0.0594, 27.2158) and (-0.1205, 27.2832) .. (-0.1827, 27.3502).. controls (-0.344, 27.5267) and (-0.344, 27.5267) .. (-0.344, 27.6754).. controls (-0.2136, 27.6846) and (-0.1373, 27.6597) .. (-0.0232, 27.5977).. controls (0.1468, 27.5062) and (0.2828, 27.4676) .. (0.4763, 27.4902).. controls (0.6696, 27.5689) and (0.7718, 27.7019) .. (0.8576, 27.8896).. controls (0.9764, 28.1869) and (1.0158, 28.4451) .. (1.0153, 28.7652).. controls (1.0153, 28.7826) and (1.0153, 28.8) .. (1.0153, 28.8179).. controls (1.0133, 29.4559) and (0.8545, 30.0395) .. (0.5821, 30.6123).. controls (0.5693, 30.6393) and (0.5565, 30.6664) .. (0.5433, 30.6943).. controls (0.4379, 30.9019) and (0.2933, 31.0653) .. (0.1251, 31.2251).. controls (0.0794, 31.2737) and (0.0794, 31.2737) .. (0.0794, 31.3267).. controls (0.0619, 31.3267) and (0.0444, 31.3267) .. (0.0265, 31.3267).. controls (0.0177, 31.3616) and (0.009, 31.3965) .. (0.0, 31.4325) -- cycle;
 \path[fill=c373435,shift={(29.21, -17.9123)}] (0.0, 31.4325).. controls (0.0087, 31.4325) and (0.0175, 31.4325) .. (0.0265, 31.4325).. controls (0.0527, 31.256) and (0.058, 31.0827) .. (0.0597, 30.9045).. controls (0.0601, 30.8733) and (0.0605, 30.8422) .. (0.0609, 30.8101).. controls (0.0642, 30.5231) and (0.0661, 30.236) .. (0.0674, 29.9489).. controls (0.0685, 29.7376) and (0.0703, 29.5262) .. (0.0731, 29.3149).. controls (0.0751, 29.1654) and (0.0761, 29.0159) .. (0.0764, 28.8663).. controls (0.0766, 28.7775) and (0.0774, 28.6887) .. (0.0789, 28.5999).. controls (0.086, 28.1667) and (0.0487, 27.8301) .. (-0.1547, 27.444).. controls (-0.2057, 27.3444) and (-0.2483, 27.2413) .. (-0.2918, 27.1383).. controls (-0.3089, 27.0988) and (-0.326, 27.0592) .. (-0.3432, 27.0198).. controls (-0.5233, 26.6047) and (-0.7021, 26.1893) .. (-0.8731, 25.7704).. controls (-0.8855, 25.7401) and (-0.8979, 25.7099) .. (-0.9107, 25.6787).. controls (-1.1705, 25.0427) and (-1.4208, 24.4033) .. (-1.5982, 23.7387).. controls (-1.6124, 23.686) and (-1.6273, 23.6335) .. (-1.6424, 23.5811).. controls (-1.8171, 22.9616) and (-1.9333, 22.311) .. (-1.9552, 21.6671).. controls (-1.9572, 21.6099) and (-1.9595, 21.5528) .. (-1.9618, 21.4956).. controls (-1.9876, 20.8733) and (-1.9801, 20.2545) .. (-1.9579, 19.6321).. controls (-2.0554, 19.578) and (-2.0554, 19.578) .. (-2.1305, 19.5888).. controls (-2.5077, 19.7143) and (-2.8375, 19.9278) .. (-3.0361, 20.2803).. controls (-3.6018, 21.5498) and (-2.9972, 23.5734) .. (-2.5854, 24.8135).. controls (-2.5667, 24.87) and (-2.5486, 24.9266) .. (-2.5306, 24.9833).. controls (-2.3429, 25.5673) and (-2.1064, 26.1343) .. (-1.8626, 26.6967).. controls (-1.8406, 26.7476) and (-1.8186, 26.7985) .. (-1.7966, 26.8494).. controls (-1.7161, 27.0356) and (-1.6334, 27.2206) .. (-1.5479, 27.4046).. controls (-1.0782, 28.4161) and (-0.6244, 29.4377) .. (-0.2836, 30.5009).. controls (-0.2707, 30.5405) and (-0.2575, 30.58) .. (-0.2439, 30.6194).. controls (-0.1914, 30.7721) and (-0.1538, 30.925) .. (-0.1201, 31.0828).. controls (-0.0923, 31.2071) and (-0.0534, 31.3168) .. (0.0, 31.4325) -- cycle;
 \path[fill=cfefefe,shift={(10.9538, -3.5454)}] (0.0, 31.4325).. controls (0.0144, 31.4215) and (0.0288, 31.4104) .. (0.0436, 31.3991).. controls (0.2828, 31.215) and (0.5137, 31.0226) .. (0.7408, 30.824).. controls (0.7633, 30.8045) and (0.7858, 30.785) .. (0.8089, 30.7649).. controls (1.1096, 30.5001) and (1.3978, 30.2174) .. (1.6404, 29.8979).. controls (1.6588, 29.8737) and (1.6773, 29.8496) .. (1.6962, 29.8246).. controls (2.2546, 29.0741) and (2.6347, 28.0396) .. (2.54, 27.0933).. controls (2.4992, 26.8752) and (2.3766, 26.7407) .. (2.196, 26.6171).. controls (2.027, 26.5405) and (1.8015, 26.533) .. (1.6226, 26.5845).. controls (1.4945, 26.6522) and (1.4295, 26.7868) .. (1.3774, 26.9179).. controls (1.2846, 27.2293) and (1.2512, 27.5631) .. (1.2187, 27.8854).. controls (1.0812, 29.2095) and (0.5342, 30.5144) .. (-0.5027, 31.3796).. controls (-0.8348, 31.6464) and (-1.2876, 32.0048) .. (-1.7297, 32.0262).. controls (-1.8284, 32.0142) and (-1.8804, 31.9963) .. (-1.9579, 31.9352).. controls (-2.0161, 31.8189) and (-1.9907, 31.6914) .. (-1.9543, 31.5724).. controls (-1.9408, 31.5404) and (-1.9272, 31.5085) .. (-1.9133, 31.4755).. controls (-1.9061, 31.4582) and (-1.8989, 31.441) .. (-1.8915, 31.4232).. controls (-1.8503, 31.3259) and (-1.8052, 31.2317) .. (-1.7562, 31.1382).. controls (-1.5804, 30.7951) and (-1.5381, 30.4247) .. (-1.527, 30.045).. controls (-1.5132, 29.5833) and (-1.4051, 29.2063) .. (-1.2171, 28.7867).. controls (-1.2089, 28.7682) and (-1.2007, 28.7498) .. (-1.1923, 28.7308).. controls (-0.923, 28.1282) and (-0.5943, 27.5209) .. (-0.1058, 27.0669).. controls (-0.0896, 27.0517) and (-0.0733, 27.0365) .. (-0.0565, 27.0209).. controls (0.3391, 26.6633) and (0.7449, 26.4731) .. (1.2668, 26.3938).. controls (1.4534, 26.3643) and (1.6085, 26.2822) .. (1.7738, 26.1945).. controls (1.867, 26.1455) and (1.9613, 26.0986) .. (2.0555, 26.0515).. controls (2.0736, 26.0424) and (2.0916, 26.0332) .. (2.1103, 26.0238).. controls (2.3077, 25.9245) and (2.5116, 25.8844) .. (2.7305, 25.9454).. controls (2.8558, 26.0093) and (2.9533, 26.1226) .. (3.0163, 26.2467).. controls (3.0647, 26.4118) and (3.0772, 26.5717) .. (3.0783, 26.743).. controls (3.0788, 26.7789) and (3.0788, 26.7789) .. (3.0794, 26.8156).. controls (3.0807, 26.8917) and (3.0816, 26.9677) .. (3.0824, 27.0437).. controls (3.0924, 27.9435) and (3.0924, 27.9435) .. (3.2279, 28.1781).. controls (3.2759, 28.2095) and (3.2759, 28.2095) .. (3.3338, 28.2046).. controls (3.4574, 28.1154) and (3.5312, 28.0255) .. (3.6, 27.8887).. controls (3.6089, 27.8713) and (3.6179, 27.8539) .. (3.6271, 27.836).. controls (3.7797, 27.5325) and (3.8678, 27.2114) .. (3.9423, 26.8817).. controls (3.9483, 26.8552) and (3.9544, 26.8287) .. (3.9606, 26.8014).. controls (4.048, 26.3766) and (3.9884, 25.941) .. (3.7835, 25.5587).. controls (3.7661, 25.5587) and (3.7486, 25.5587) .. (3.7306, 25.5587).. controls (3.7216, 25.5358) and (3.7216, 25.5358) .. (3.7124, 25.5124).. controls (3.6432, 25.3937) and (3.5316, 25.3257) .. (3.4027, 25.2822).. controls (2.838, 25.1636) and (2.2172, 25.4642) .. (1.7512, 25.7603).. controls (1.6384, 25.8316) and (1.5198, 25.8926) .. (1.4023, 25.9556).. controls (1.369, 25.9738) and (1.3357, 25.992) .. (1.3025, 26.0102).. controls (1.0993, 26.1204) and (0.8945, 26.2215) .. (0.683, 26.3145).. controls (-0.3525, 26.7725) and (-1.0957, 27.6557) .. (-1.5048, 28.7073).. controls (-1.5238, 28.7601) and (-1.5426, 28.813) .. (-1.561, 28.866).. controls (-1.5685, 28.8853) and (-1.576, 28.9045) .. (-1.5838, 28.9243).. controls (-1.6964, 29.2253) and (-1.7217, 29.5521) .. (-1.7446, 29.8698).. controls (-1.7837, 30.3842) and (-1.9075, 30.7726) .. (-2.1646, 31.2175).. controls (-2.2867, 31.4353) and (-2.343, 31.6857) .. (-2.3283, 31.9352).. controls (-2.2823, 32.098) and (-2.202, 32.2152) .. (-2.0622, 32.3099).. controls (-1.3873, 32.6018) and (-0.4928, 31.8124) .. (0.0, 31.4325) -- cycle;
 \path[fill=c373435,shift={(12.4883, -19.8967)}] (0.0, 31.4325).. controls (0.4026, 31.1094) and (0.6644, 30.6769) .. (0.7408, 30.1625).. controls (0.7498, 30.0169) and (0.7512, 29.8717) .. (0.7508, 29.7259).. controls (0.7507, 29.7058) and (0.7507, 29.6857) .. (0.7507, 29.665).. controls (0.7496, 29.3686) and (0.7381, 29.0941) .. (0.635, 28.8131).. controls (0.6285, 28.7952) and (0.6219, 28.7773) .. (0.6152, 28.7589).. controls (0.4533, 28.3267) and (0.1921, 27.9635) .. (-0.2099, 27.7256).. controls (-0.228, 27.7178) and (-0.246, 27.71) .. (-0.2646, 27.7019).. controls (-0.282, 27.7106) and (-0.2995, 27.7193) .. (-0.3175, 27.7283).. controls (-0.2983, 27.8981) and (-0.2476, 28.0461) .. (-0.1893, 28.2069).. controls (-0.0168, 28.7424) and (-0.0881, 29.495) .. (-0.3175, 30.0038).. controls (-0.4297, 30.2161) and (-0.6137, 30.3212) .. (-0.8311, 30.4069).. controls (-0.9821, 30.4513) and (-1.1388, 30.4588) .. (-1.2952, 30.4668).. controls (-1.3246, 30.4684) and (-1.3246, 30.4684) .. (-1.3546, 30.47).. controls (-1.4168, 30.4734) and (-1.479, 30.4767) .. (-1.5412, 30.48).. controls (-1.603, 30.4833) and (-1.6648, 30.4866) .. (-1.7266, 30.49).. controls (-1.7649, 30.4921) and (-1.8032, 30.4941) .. (-1.8414, 30.4961).. controls (-1.9447, 30.5017) and (-2.0473, 30.5099) .. (-2.1502, 30.5201).. controls (-2.4025, 30.5435) and (-2.656, 30.5409) .. (-2.9092, 30.5422).. controls (-2.9733, 30.5426) and (-3.0374, 30.5433) .. (-3.1014, 30.5444).. controls (-3.8667, 30.5564) and (-4.6118, 30.4475) .. (-5.2388, 29.9773).. controls (-5.2562, 29.9773) and (-5.2737, 29.9773) .. (-5.2917, 29.9773).. controls (-5.2917, 29.9598) and (-5.2917, 29.9424) .. (-5.2917, 29.9244).. controls (-5.371, 29.8715) and (-5.371, 29.8715) .. (-5.4289, 29.8814).. controls (-5.4447, 29.8868) and (-5.4606, 29.8923) .. (-5.4769, 29.8979).. controls (-5.4602, 30.0261) and (-5.4238, 30.1416) .. (-5.3777, 30.2617).. controls (-5.3669, 30.2898) and (-5.3669, 30.2898) .. (-5.356, 30.3184).. controls (-5.201, 30.7175) and (-4.991, 31.0269) .. (-4.6567, 31.3002).. controls (-4.632, 31.3206) and (-4.632, 31.3206) .. (-4.6069, 31.3414).. controls (-4.431, 31.468) and (-4.202, 31.5112) .. (-3.9952, 31.5648).. controls (-3.9474, 31.5779) and (-3.9474, 31.5779) .. (-3.8985, 31.5913).. controls (-3.7751, 31.622) and (-3.6518, 31.6346) .. (-3.5253, 31.6462).. controls (-3.4743, 31.6513) and (-3.4234, 31.6563) .. (-3.3724, 31.6614).. controls (-3.3326, 31.6652) and (-3.3326, 31.6652) .. (-3.292, 31.6692).. controls (-2.8183, 31.7156) and (-2.3492, 31.773) .. (-1.881, 31.859).. controls (-1.2033, 31.981) and (-0.5571, 31.8465) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(15.9544, -6.7998)}] (0.0, 31.4325).. controls (0.429, 31.3142) and (0.7885, 31.027) .. (1.1248, 30.7464).. controls (1.1629, 30.7148) and (1.2014, 30.6835) .. (1.2408, 30.6534).. controls (2.1409, 29.9493) and (2.3426, 28.434) .. (2.5268, 27.3877).. controls (2.6413, 26.7449) and (2.8449, 26.151) .. (3.1244, 25.5627).. controls (3.4398, 24.8877) and (3.6943, 24.18) .. (3.81, 23.4421).. controls (3.8128, 23.4248) and (3.8156, 23.4076) .. (3.8185, 23.3898).. controls (4.0276, 22.0377) and (3.8589, 20.4072) .. (3.0661, 19.2691).. controls (3.0496, 19.2492) and (3.0332, 19.2293) .. (3.0163, 19.2088).. controls (2.9988, 19.2088) and (2.9813, 19.2088) .. (2.9633, 19.2088).. controls (2.957, 19.1934) and (2.9507, 19.1781) .. (2.9442, 19.1622).. controls (2.8254, 18.9536) and (2.5218, 18.7829) .. (2.2971, 18.7151).. controls (1.9091, 18.6115) and (1.9091, 18.6115) .. (1.7727, 18.6531).. controls (1.7849, 18.7789) and (1.8346, 18.8337) .. (1.9215, 18.9227).. controls (2.046, 19.0539) and (2.1489, 19.1907) .. (2.249, 19.341).. controls (2.2782, 19.3819) and (2.2782, 19.3819) .. (2.308, 19.4235).. controls (3.0328, 20.4481) and (3.4785, 21.9244) .. (3.2841, 23.1808).. controls (3.2794, 23.205) and (3.2746, 23.2291) .. (3.2697, 23.254).. controls (3.2548, 23.3337) and (3.2445, 23.413) .. (3.2343, 23.4934).. controls (3.2034, 23.6953) and (3.1395, 23.8811) .. (3.0692, 24.0721).. controls (3.0562, 24.1081) and (3.0432, 24.1441) .. (3.0302, 24.1801).. controls (2.93, 24.4557) and (2.8195, 24.7264) .. (2.7046, 24.9961).. controls (2.6259, 25.1812) and (2.5519, 25.3682) .. (2.4871, 25.5587).. controls (2.4747, 25.5944) and (2.4747, 25.5944) .. (2.462, 25.6308).. controls (2.3883, 25.8541) and (2.3477, 26.076) .. (2.313, 26.3077).. controls (2.2967, 26.416) and (2.2794, 26.5241) .. (2.2623, 26.6323).. controls (2.2589, 26.6537) and (2.2555, 26.6752) .. (2.252, 26.6973).. controls (2.0968, 27.6775) and (1.8539, 28.8107) .. (1.1377, 29.554).. controls (1.1115, 29.5627) and (1.0853, 29.5714) .. (1.0583, 29.5804).. controls (1.0764, 29.3979) and (1.1168, 29.2242) .. (1.1609, 29.0463).. controls (1.1753, 28.9867) and (1.1898, 28.9272) .. (1.2043, 28.8676).. controls (1.2254, 28.7814) and (1.2466, 28.6952) .. (1.2679, 28.609).. controls (1.3747, 28.1671) and (1.4492, 27.7339) .. (1.4288, 27.2785).. controls (1.3938, 27.2785) and (1.3589, 27.2785) .. (1.3229, 27.2785).. controls (1.3068, 27.3254) and (1.2909, 27.3722) .. (1.275, 27.4191).. controls (1.2661, 27.4452) and (1.2572, 27.4713) .. (1.248, 27.4982).. controls (1.1735, 27.7339) and (1.1214, 27.9673) .. (1.0815, 28.2112).. controls (0.8997, 29.2652) and (0.6696, 30.3867) .. (0.0468, 31.2789).. controls (0.0, 31.3531) and (0.0, 31.3531) .. (0.0, 31.4325) -- cycle;
  \path[fill=c373435,shift={(10.9266, -12.7988)}] (0.0, 31.4325).. controls (0.0521, 31.4326) and (0.0521, 31.4326) .. (0.1053, 31.4327).. controls (0.1232, 31.4326) and (0.1411, 31.4325) .. (0.1596, 31.4324).. controls (0.2133, 31.4321) and (0.267, 31.4324) .. (0.3207, 31.4327).. controls (0.4878, 31.4329) and (0.6498, 31.4259) .. (0.8152, 31.3988).. controls (1.0495, 31.3616) and (1.2823, 31.3668) .. (1.5188, 31.3692).. controls (1.5642, 31.3695) and (1.6097, 31.3698) .. (1.6552, 31.37).. controls (1.7652, 31.3705) and (1.8751, 31.3715) .. (1.9851, 31.3726).. controls (2.0008, 31.3103) and (2.0008, 31.3103) .. (2.0116, 31.2403).. controls (1.9714, 31.1778) and (1.9714, 31.1778) .. (1.9107, 31.1146).. controls (1.8888, 31.0912) and (1.8668, 31.0678) .. (1.8442, 31.0437).. controls (1.7734, 30.9757) and (1.7734, 30.9757) .. (1.7051, 30.9242).. controls (1.477, 30.7511) and (1.428, 30.5349) .. (1.345, 30.2726).. controls (1.22, 29.8972) and (0.9916, 29.5812) .. (0.6408, 29.3905).. controls (0.6217, 29.381) and (0.6025, 29.3715) .. (0.5828, 29.3617).. controls (0.5664, 29.3526) and (0.5499, 29.3435) .. (0.533, 29.3341).. controls (0.2352, 29.1994) and (-0.1775, 29.3308) .. (-0.4661, 29.4302).. controls (-0.715, 29.5151) and (-1.012, 29.5384) .. (-1.2614, 29.4446).. controls (-1.3627, 29.3946) and (-1.455, 29.3317) .. (-1.5476, 29.2672).. controls (-1.6132, 29.2294) and (-1.6132, 29.2294) .. (-1.7191, 29.2294).. controls (-1.7274, 29.3752) and (-1.7024, 29.4883) .. (-1.6463, 29.6213).. controls (-1.6383, 29.6406) and (-1.6303, 29.6598) .. (-1.6221, 29.6796).. controls (-1.5003, 29.957) and (-1.3216, 30.2056) .. (-1.1362, 30.4438).. controls (-1.0321, 30.5815) and (-0.9569, 30.7342) .. (-0.8786, 30.8875).. controls (-0.7386, 31.1518) and (-0.5698, 31.3078) .. (-0.285, 31.3999).. controls (-0.1855, 31.4252) and (-0.1023, 31.4323) .. (0.0, 31.4325) -- cycle;
  \path[fill=c373435,shift={(29.21, -24.0771)}] (0.0, 31.4325).. controls (0.0686, 31.3299) and (0.0603, 31.222) .. (0.0596, 31.1034).. controls (0.0597, 31.0806) and (0.0598, 31.0579) .. (0.0599, 31.0344).. controls (0.0601, 30.9581) and (0.0599, 30.8818) .. (0.0598, 30.8054).. controls (0.0598, 30.7508) and (0.0599, 30.6961) .. (0.06, 30.6414).. controls (0.0603, 30.4929) and (0.0602, 30.3443) .. (0.06, 30.1957).. controls (0.0599, 30.0404) and (0.06, 29.8852) .. (0.0601, 29.7299).. controls (0.0602, 29.4692) and (0.0601, 29.2084) .. (0.0598, 28.9477).. controls (0.0595, 28.6459) and (0.0596, 28.3441) .. (0.0599, 28.0423).. controls (0.0602, 27.7835) and (0.0602, 27.5247) .. (0.06, 27.2659).. controls (0.06, 27.1112) and (0.06, 26.9565) .. (0.0601, 26.8018).. controls (0.0603, 26.6564) and (0.0602, 26.511) .. (0.0599, 26.3657).. controls (0.0598, 26.3122) and (0.0598, 26.2587) .. (0.0599, 26.2052).. controls (0.0601, 26.1325) and (0.0599, 26.0597) .. (0.0596, 25.987).. controls (0.0598, 25.9656) and (0.0599, 25.9442) .. (0.06, 25.9222).. controls (0.059, 25.7765) and (0.059, 25.7765) .. (0.0, 25.7175).. controls (-0.1048, 25.7047) and (-0.2104, 25.7077) .. (-0.3158, 25.7076).. controls (-0.3452, 25.7069) and (-0.3746, 25.7063) .. (-0.4049, 25.7056).. controls (-0.433, 25.7055) and (-0.4612, 25.7054) .. (-0.4902, 25.7053).. controls (-0.529, 25.705) and (-0.529, 25.705) .. (-0.5685, 25.7046).. controls (-0.635, 25.7175) and (-0.635, 25.7175) .. (-0.6819, 25.7631).. controls (-0.7168, 25.8278) and (-0.7319, 25.8798) .. (-0.7443, 25.9521).. controls (-0.7487, 25.9774) and (-0.7531, 26.0027) .. (-0.7577, 26.0288).. controls (-0.7619, 26.0559) and (-0.7662, 26.0831) .. (-0.7706, 26.1111).. controls (-0.7751, 26.1394) and (-0.7797, 26.1678) .. (-0.7844, 26.197).. controls (-0.827, 26.478) and (-0.843, 26.7564) .. (-0.8467, 27.0404).. controls (-0.8471, 27.0679) and (-0.8475, 27.0954) .. (-0.8479, 27.1238).. controls (-0.8504, 27.3253) and (-0.8494, 27.5268) .. (-0.8467, 27.7283).. controls (-0.8465, 27.7517) and (-0.8463, 27.7751) .. (-0.8461, 27.7992).. controls (-0.8389, 28.4222) and (-0.7178, 29.0532) .. (-0.5821, 29.6598).. controls (-0.5763, 29.6856) and (-0.5706, 29.7114) .. (-0.5646, 29.738).. controls (-0.4862, 30.0849) and (-0.3977, 30.426) .. (-0.2847, 30.7633).. controls (-0.2634, 30.8274) and (-0.2432, 30.8917) .. (-0.223, 30.9561).. controls (-0.2093, 30.9992) and (-0.1956, 31.0422) .. (-0.1819, 31.0852).. controls (-0.1758, 31.1049) and (-0.1698, 31.1246) .. (-0.1635, 31.1449).. controls (-0.1261, 31.2598) and (-0.083, 31.3416) .. (0.0, 31.4325) -- cycle;
  \path[fill=c373435,shift={(12.6471, -13.7319)}] (0.0, 31.4325).. controls (0.0546, 31.4127) and (0.0546, 31.4127) .. (0.1058, 31.3796).. controls (0.2165, 31.0475) and (0.1603, 30.5457) .. (0.0529, 30.2154).. controls (0.0439, 30.1869) and (0.0349, 30.1585) .. (0.0256, 30.1291).. controls (-0.1444, 29.6437) and (-0.4649, 29.2748) .. (-0.8731, 28.9719).. controls (-0.9134, 28.9419) and (-0.9134, 28.9419) .. (-0.9546, 28.9114).. controls (-1.4719, 28.542) and (-2.222, 28.0825) .. (-2.884, 28.1252).. controls (-2.9415, 28.166) and (-2.9585, 28.195) .. (-2.9898, 28.2575).. controls (-2.9975, 28.6287) and (-2.853, 28.9115) .. (-2.6458, 29.21).. controls (-2.632, 29.2302) and (-2.6181, 29.2504) .. (-2.6039, 29.2712).. controls (-2.5915, 29.2859) and (-2.5792, 29.3007) .. (-2.5665, 29.3158).. controls (-2.549, 29.3158) and (-2.5315, 29.3158) .. (-2.5135, 29.3158).. controls (-2.5004, 29.3551) and (-2.5004, 29.3551) .. (-2.4871, 29.3952).. controls (-2.3591, 29.5232) and (-2.2095, 29.5762) .. (-2.031, 29.5843).. controls (-1.9679, 29.5839) and (-1.9049, 29.5831) .. (-1.8419, 29.582).. controls (-1.3902, 29.5746) and (-1.0436, 29.6944) .. (-0.7096, 30.0044).. controls (-0.377, 30.3525) and (-0.2264, 30.8219) .. (-0.0965, 31.2747).. controls (-0.0834, 31.319) and (-0.0684, 31.3626) .. (-0.0529, 31.406).. controls (-0.0355, 31.4148) and (-0.018, 31.4235) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(13.8377, -12.5413)}] (0.0, 31.4325).. controls (0.048, 31.4184) and (0.048, 31.4184) .. (0.1058, 31.3796).. controls (0.1374, 31.3128) and (0.1618, 31.2514) .. (0.1845, 31.1817).. controls (0.1946, 31.1517) and (0.1946, 31.1517) .. (0.205, 31.1211).. controls (0.2713, 30.9195) and (0.3207, 30.7145) .. (0.3677, 30.5077).. controls (0.4525, 30.1369) and (0.5459, 29.7753) .. (0.6879, 29.4217).. controls (0.6959, 29.4012) and (0.7039, 29.3807) .. (0.7122, 29.3597).. controls (0.8815, 28.9283) and (1.0892, 28.5186) .. (1.3452, 28.1322).. controls (1.4385, 27.991) and (1.5262, 27.8465) .. (1.614, 27.7019).. controls (1.6291, 27.6776) and (1.6443, 27.6534) .. (1.66, 27.6284).. controls (1.937, 27.1742) and (2.1191, 26.6647) .. (2.3019, 26.1673).. controls (2.3134, 26.136) and (2.3249, 26.1047) .. (2.3368, 26.0724).. controls (2.5472, 25.4948) and (2.7599, 24.8971) .. (2.7533, 24.2755).. controls (2.7532, 24.2538) and (2.7531, 24.232) .. (2.753, 24.2096).. controls (2.7527, 24.1566) and (2.7522, 24.1036) .. (2.7517, 24.0506).. controls (2.7167, 24.0506) and (2.6818, 24.0506) .. (2.6458, 24.0506).. controls (2.64, 24.0686) and (2.6341, 24.0866) .. (2.6281, 24.1051).. controls (2.6011, 24.1879) and (2.5738, 24.2706) .. (2.5466, 24.3532).. controls (2.5374, 24.3815) and (2.5282, 24.4098) .. (2.5187, 24.439).. controls (2.4422, 24.6708) and (2.3522, 24.8853) .. (2.2341, 25.099).. controls (2.0868, 25.3702) and (1.9574, 25.6502) .. (1.8256, 25.9292).. controls (1.7909, 26.0025) and (1.7561, 26.0758) .. (1.7213, 26.1491).. controls (1.7005, 26.1931) and (1.6797, 26.237) .. (1.6589, 26.2809).. controls (1.6037, 26.3974) and (1.5469, 26.5128) .. (1.4884, 26.6276).. controls (1.3545, 26.8913) and (1.2363, 27.1608) .. (1.1195, 27.4323).. controls (1.0809, 27.5218) and (1.0422, 27.6113) .. (1.0035, 27.7007).. controls (0.9943, 27.722) and (0.9851, 27.7432) .. (0.9757, 27.7651).. controls (0.9269, 27.8778) and (0.8773, 27.99) .. (0.8261, 28.1015).. controls (0.7685, 28.2271) and (0.7157, 28.354) .. (0.6648, 28.4824).. controls (0.6557, 28.5051) and (0.6467, 28.5278) .. (0.6374, 28.5512).. controls (0.4091, 29.1292) and (0.1921, 29.7148) .. (0.0529, 30.3212).. controls (0.0485, 30.3378) and (0.044, 30.3543) .. (0.0395, 30.3714).. controls (-0.0228, 30.6039) and (-0.0307, 30.8321) .. (-0.0298, 31.072).. controls (-0.0299, 31.098) and (-0.03, 31.1241) .. (-0.0301, 31.1509).. controls (-0.03, 31.1758) and (-0.03, 31.2007) .. (-0.03, 31.2264).. controls (-0.0299, 31.2489) and (-0.0299, 31.2713) .. (-0.0299, 31.2945).. controls (-0.0265, 31.3531) and (-0.0265, 31.3531) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(17.1715, -4.2863)}] (0.0, 31.4325).. controls (0.0262, 31.4238) and (0.0524, 31.415) .. (0.0794, 31.406).. controls (0.0715, 31.3891) and (0.0637, 31.3722) .. (0.0556, 31.3548).. controls (-0.0946, 30.9371) and (-0.0802, 30.48) .. (0.0265, 30.0567).. controls (0.0701, 30.0479) and (0.1138, 30.0392) .. (0.1588, 30.0302).. controls (0.1745, 30.0533) and (0.1902, 30.0763) .. (0.2064, 30.1001).. controls (0.3605, 30.3228) and (0.5261, 30.5235) .. (0.7144, 30.7181).. controls (0.7351, 30.74) and (0.7559, 30.7618) .. (0.7773, 30.7843).. controls (1.0405, 31.0553) and (1.0405, 31.0553) .. (1.1906, 31.1415).. controls (1.2168, 31.1327) and (1.243, 31.124) .. (1.27, 31.115).. controls (1.2255, 30.9772) and (1.1777, 30.8415) .. (1.1245, 30.7068).. controls (1.0131, 30.4238) and (0.9147, 30.1368) .. (0.8186, 29.8483).. controls (0.8083, 29.8175) and (0.8083, 29.8175) .. (0.7978, 29.786).. controls (0.704, 29.5043) and (0.6133, 29.2218) .. (0.5353, 28.9351).. controls (0.5093, 28.8444) and (0.4882, 28.7754) .. (0.4294, 28.7009).. controls (0.3358, 28.6691) and (0.282, 28.7054) .. (0.1935, 28.7453).. controls (0.1579, 28.7608) and (0.1223, 28.7761) .. (0.0867, 28.7914).. controls (0.0589, 28.8035) and (0.0589, 28.8035) .. (0.0306, 28.8158).. controls (-0.0631, 28.8549) and (-0.1587, 28.8876) .. (-0.2547, 28.9206).. controls (-0.3947, 28.9694) and (-0.5343, 29.0189) .. (-0.673, 29.0711).. controls (-0.7003, 29.0813) and (-0.7275, 29.0916) .. (-0.7556, 29.1021).. controls (-0.8202, 29.1306) and (-0.8202, 29.1306) .. (-0.8731, 29.1835).. controls (-0.8987, 29.7631) and (-0.643, 30.3818) .. (-0.382, 30.8851).. controls (-0.3705, 30.9074) and (-0.359, 30.9296) .. (-0.3472, 30.9526).. controls (-0.2528, 31.128) and (-0.1412, 31.2913) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(23.3098, -6.7469)}] (0.0, 31.4325).. controls (-0.0586, 31.3426) and (-0.1127, 31.3028) .. (-0.2084, 31.2556).. controls (-0.6653, 31.0156) and (-1.1252, 30.6658) .. (-1.3091, 30.1657).. controls (-1.3271, 30.1021) and (-1.3271, 30.1021) .. (-1.3229, 30.0038).. controls (-1.045, 30.0514) and (-0.7838, 30.132) .. (-0.5242, 30.2419).. controls (-0.3037, 30.3347) and (-0.0753, 30.3815) .. (0.1588, 30.4271).. controls (0.1675, 30.4009) and (0.1762, 30.3747) .. (0.1852, 30.3477).. controls (0.0897, 30.2508) and (-0.0086, 30.1582) .. (-0.1091, 30.0666).. controls (-0.3839, 29.8139) and (-0.6385, 29.5538) .. (-0.8656, 29.2564).. controls (-0.9633, 29.1328) and (-0.9633, 29.1328) .. (-1.0425, 29.1218).. controls (-1.121, 29.1319) and (-1.1598, 29.153) .. (-1.2254, 29.1968).. controls (-1.5728, 29.4148) and (-1.9567, 29.5779) .. (-2.3259, 29.7559).. controls (-2.5126, 29.8459) and (-2.6989, 29.9367) .. (-2.884, 30.0302).. controls (-2.6167, 30.3973) and (-2.0189, 30.6001) .. (-1.6175, 30.7869).. controls (-1.4662, 30.8578) and (-1.3182, 30.9338) .. (-1.1708, 31.0125).. controls (-0.3239, 31.4626) and (-0.3239, 31.4626) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(7.911, -10.6363)}] (0.0, 31.4325).. controls (0.0087, 31.4063) and (0.0175, 31.3801) .. (0.0265, 31.3531).. controls (0.0036, 31.311) and (0.0036, 31.311) .. (-0.0347, 31.2605).. controls (-0.2967, 30.883) and (-0.4675, 30.4651) .. (-0.6085, 30.0302).. controls (-0.6179, 30.0017) and (-0.6273, 29.9732) .. (-0.637, 29.9438).. controls (-0.8721, 29.2188) and (-1.0316, 28.4725) .. (-1.2024, 27.7303).. controls (-1.4478, 26.6642) and (-1.7264, 25.62) .. (-2.0867, 24.5866).. controls (-2.1118, 24.5144) and (-2.1367, 24.4422) .. (-2.1615, 24.3699).. controls (-2.2375, 24.1496) and (-2.321, 23.933) .. (-2.4086, 23.717).. controls (-2.4652, 23.5771) and (-2.5194, 23.4365) .. (-2.5714, 23.2949).. controls (-2.623, 23.1548) and (-2.6807, 23.0193) .. (-2.7441, 22.8842).. controls (-2.7944, 22.7701) and (-2.8366, 22.6532) .. (-2.8797, 22.5363).. controls (-2.921, 22.4247) and (-2.9656, 22.3161) .. (-3.0149, 22.2079).. controls (-3.1824, 21.8325) and (-3.3137, 21.4417) .. (-3.43, 21.0477).. controls (-3.4369, 21.0246) and (-3.4438, 21.0015) .. (-3.451, 20.9777).. controls (-3.464, 20.9338) and (-3.4768, 20.8897) .. (-3.4891, 20.8456).. controls (-3.5328, 20.6993) and (-3.5328, 20.6993) .. (-3.603, 20.6502).. controls (-3.6269, 20.6439) and (-3.6269, 20.6439) .. (-3.6513, 20.6375).. controls (-3.7504, 20.7367) and (-3.7356, 20.8546) .. (-3.7372, 20.9897).. controls (-3.737, 21.463) and (-3.5634, 21.8439) .. (-3.3685, 22.2663).. controls (-3.3478, 22.3112) and (-3.3478, 22.3112) .. (-3.3267, 22.3569).. controls (-3.2142, 22.5985) and (-3.0926, 22.8341) .. (-2.9666, 23.0688).. controls (-2.6168, 23.725) and (-2.3368, 24.4053) .. (-2.1084, 25.1123).. controls (-2.0999, 25.1384) and (-2.0999, 25.1384) .. (-2.0913, 25.1651).. controls (-1.9954, 25.463) and (-1.9116, 25.7618) .. (-1.8405, 26.0664).. controls (-1.7928, 26.2686) and (-1.7439, 26.4703) .. (-1.6931, 26.6718).. controls (-1.6891, 26.6877) and (-1.6851, 26.7036) .. (-1.681, 26.72).. controls (-1.6702, 26.7629) and (-1.6592, 26.8057) .. (-1.6482, 26.8485).. controls (-1.603, 27.0263) and (-1.5632, 27.2043) .. (-1.528, 27.3844).. controls (-1.5225, 27.412) and (-1.517, 27.4396) .. (-1.5113, 27.468).. controls (-1.4809, 27.6213) and (-1.4513, 27.7748) .. (-1.4225, 27.9284).. controls (-1.3399, 28.3681) and (-1.2568, 28.8043) .. (-1.128, 29.2334).. controls (-1.113, 29.2835) and (-1.0986, 29.3338) .. (-1.0844, 29.3841).. controls (-0.9, 30.0176) and (-0.5922, 30.9115) .. (-0.0794, 31.3531).. controls (-0.0619, 31.3531) and (-0.0445, 31.3531) .. (-0.0265, 31.3531).. controls (-0.0177, 31.3793) and (-0.009, 31.4055) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(27.5696, -10.0542)}] (0.0, 31.4325).. controls (-0.102, 31.3532) and (-0.2026, 31.2884) .. (-0.3225, 31.239).. controls (-0.7359, 31.0648) and (-1.076, 30.771) .. (-1.3229, 30.4006).. controls (-1.3229, 30.3744) and (-1.3229, 30.3482) .. (-1.3229, 30.3212).. controls (-1.2307, 30.2905) and (-1.2003, 30.3007) .. (-1.1083, 30.326).. controls (-1.0818, 30.3331) and (-1.0553, 30.3403) .. (-1.028, 30.3476).. controls (-1.0004, 30.3553) and (-0.9727, 30.363) .. (-0.9442, 30.3709).. controls (-0.8898, 30.3857) and (-0.8353, 30.4006) .. (-0.7808, 30.4153).. controls (-0.7446, 30.4253) and (-0.7446, 30.4253) .. (-0.7076, 30.4355).. controls (-0.5179, 30.4826) and (-0.335, 30.4857) .. (-0.1406, 30.4866).. controls (-0.1104, 30.4872) and (-0.0802, 30.4877) .. (-0.0491, 30.4883).. controls (-0.0203, 30.4884) and (0.0086, 30.4885) .. (0.0383, 30.4887).. controls (0.0778, 30.4891) and (0.0778, 30.4891) .. (0.118, 30.4894).. controls (0.1948, 30.4787) and (0.2177, 30.4608) .. (0.2646, 30.4006).. controls (0.2031, 30.3319) and (0.1419, 30.2953) .. (0.0592, 30.2552).. controls (0.0342, 30.2428) and (0.0091, 30.2303) .. (-0.0167, 30.2175).. controls (-0.0567, 30.1977) and (-0.0567, 30.1977) .. (-0.0976, 30.1774).. controls (-0.4562, 29.9949) and (-0.7683, 29.7766) .. (-1.0528, 29.4916).. controls (-1.1257, 29.4374) and (-1.18, 29.4273) .. (-1.27, 29.4217).. controls (-1.3328, 29.4564) and (-1.3328, 29.4564) .. (-1.3758, 29.501).. controls (-1.3758, 29.5185) and (-1.3758, 29.536) .. (-1.3758, 29.554).. controls (-1.3905, 29.5604) and (-1.4051, 29.5669) .. (-1.4202, 29.5735).. controls (-1.4945, 29.6139) and (-1.5541, 29.6633) .. (-1.6189, 29.7177).. controls (-1.7062, 29.7901) and (-1.7935, 29.8619) .. (-1.8835, 29.931).. controls (-1.9605, 29.9903) and (-2.0363, 30.0509) .. (-2.1114, 30.1126).. controls (-2.382, 30.3361) and (-2.382, 30.3361) .. (-2.6723, 30.5329).. controls (-2.6625, 30.5983) and (-2.6538, 30.6312) .. (-2.6051, 30.6773).. controls (-1.9999, 31.0706) and (-1.26, 31.2621) .. (-0.5556, 31.3796).. controls (-0.5278, 31.3845) and (-0.4999, 31.3894) .. (-0.4712, 31.3945).. controls (-0.4294, 31.4017) and (-0.4294, 31.4017) .. (-0.3867, 31.4091).. controls (-0.3616, 31.4135) and (-0.3365, 31.4179) .. (-0.3106, 31.4225).. controls (-0.2059, 31.437) and (-0.1054, 31.436) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(21.0079, -5.6621)}] (0.0, 31.4325).. controls (-0.1125, 31.347) and (-0.2258, 31.2636) .. (-0.3416, 31.1827).. controls (-0.6559, 30.962) and (-0.9326, 30.7363) .. (-1.1642, 30.4271).. controls (-1.187, 30.4) and (-1.187, 30.4) .. (-1.2103, 30.3724).. controls (-1.2532, 30.3166) and (-1.2532, 30.3166) .. (-1.2435, 30.2154).. controls (-1.2297, 30.2247) and (-1.2159, 30.234) .. (-1.2017, 30.2436).. controls (-0.9221, 30.4312) and (-0.6384, 30.608) .. (-0.344, 30.771).. controls (-0.3208, 30.7839) and (-0.2976, 30.7968) .. (-0.2737, 30.8101).. controls (-0.0767, 30.9144) and (0.1454, 31.0092) .. (0.3704, 31.0092).. controls (0.331, 30.8962) and (0.2501, 30.8539) .. (0.1521, 30.7958).. controls (-0.316, 30.5054) and (-0.7254, 30.1291) .. (-1.0848, 29.7127).. controls (-1.1464, 29.6444) and (-1.2082, 29.5763) .. (-1.2702, 29.5084).. controls (-1.3148, 29.4574) and (-1.3534, 29.4058) .. (-1.3924, 29.3506).. controls (-1.4131, 29.3304) and (-1.4338, 29.3102) .. (-1.4552, 29.2894).. controls (-1.5913, 29.2964) and (-1.6932, 29.3347) .. (-1.814, 29.3952).. controls (-2.0563, 29.5135) and (-2.306, 29.6125) .. (-2.5559, 29.7133).. controls (-2.6393, 29.7473) and (-2.722, 29.7827) .. (-2.8046, 29.8185).. controls (-2.7904, 29.9841) and (-2.6761, 30.0594) .. (-2.558, 30.162).. controls (-2.0741, 30.5656) and (-0.6512, 31.6346) .. (0.0, 31.4325) -- cycle;
  \path[fill=c373435,shift={(9.4652, -15.3015)}] (0.0, 31.4325).. controls (0.0296, 31.4236) and (0.0296, 31.4236) .. (0.0598, 31.4146).. controls (0.0674, 31.2325) and (0.0441, 31.0827) .. (-0.008, 30.9086).. controls (-0.0151, 30.8844) and (-0.0221, 30.8602) .. (-0.0295, 30.8352).. controls (-0.0947, 30.6204) and (-0.1806, 30.4228) .. (-0.2841, 30.224).. controls (-0.2972, 30.1977) and (-0.3102, 30.1714) .. (-0.3237, 30.1443).. controls (-0.413, 29.9709) and (-0.5187, 29.8094) .. (-0.6545, 29.6684).. controls (-0.672, 29.6684) and (-0.6895, 29.6684) .. (-0.7075, 29.6684).. controls (-0.7075, 29.6509) and (-0.7075, 29.6334) .. (-0.7075, 29.6155).. controls (-0.7398, 29.5819) and (-0.7398, 29.5819) .. (-0.7885, 29.541).. controls (-0.8076, 29.5247) and (-0.8267, 29.5084) .. (-0.8465, 29.4916).. controls (-0.8704, 29.4714) and (-0.8944, 29.4511) .. (-0.9191, 29.4302).. controls (-1.1438, 29.2385) and (-1.364, 29.0467) .. (-1.5678, 28.8325).. controls (-1.5976, 28.8016) and (-1.6287, 28.7718) .. (-1.66, 28.7423).. controls (-1.6774, 28.7423) and (-1.6949, 28.7423) .. (-1.7129, 28.7423).. controls (-1.72, 28.7264) and (-1.7271, 28.7105) .. (-1.7345, 28.6941).. controls (-1.7661, 28.636) and (-1.7945, 28.6056) .. (-1.8435, 28.5621).. controls (-2.2981, 28.1198) and (-2.557, 27.5144) .. (-2.7303, 26.915).. controls (-2.754, 26.8338) and (-2.7766, 26.7764) .. (-2.8241, 26.705).. controls (-2.8503, 26.7138) and (-2.8765, 26.7225) .. (-2.9035, 26.7315).. controls (-2.9187, 27.4924) and (-2.584, 28.1034) .. (-2.1011, 28.6634).. controls (-2.0876, 28.6791) and (-2.0741, 28.6948) .. (-2.0601, 28.7109).. controls (-2.0465, 28.7266) and (-2.0329, 28.7424) .. (-2.0189, 28.7586).. controls (-1.8953, 28.9025) and (-1.7797, 29.0516) .. (-1.6655, 29.203).. controls (-1.6339, 29.2445) and (-1.6017, 29.2854) .. (-1.5694, 29.3263).. controls (-1.2883, 29.6834) and (-1.0482, 30.0644) .. (-0.8205, 30.4572).. controls (-0.2361, 31.4605) and (-0.2361, 31.4605) .. (0.0, 31.4325) -- cycle;
  \path[fill=cfefefe,shift={(24.5004, -8.89)}] (0.0, 31.4325).. controls (-0.0108, 31.3431) and (-0.0308, 31.2934) .. (-0.0794, 31.2159).. controls (-0.1473, 31.1031) and (-0.1656, 30.9812) .. (-0.1588, 30.8504).. controls (-0.115, 30.7664) and (-0.115, 30.7664) .. (-0.0431, 30.7526).. controls (0.1238, 30.7386) and (0.291, 30.7457) .. (0.4583, 30.7503).. controls (0.4858, 30.7506) and (0.5133, 30.751) .. (0.5417, 30.7514).. controls (0.579, 30.7523) and (0.579, 30.7523) .. (0.6171, 30.7532).. controls (0.7012, 30.743) and (0.751, 30.7128) .. (0.8202, 30.6652).. controls (0.7381, 30.574) and (0.6538, 30.5224) .. (0.5457, 30.4651).. controls (0.4034, 30.3871) and (0.2742, 30.2999) .. (0.1472, 30.1989).. controls (0.1316, 30.1865) and (0.116, 30.1741) .. (0.0999, 30.1613).. controls (0.0196, 30.0965) and (-0.0563, 30.0288) .. (-0.1306, 29.9574).. controls (-0.2117, 29.8979) and (-0.2117, 29.8979) .. (-0.2998, 29.8999).. controls (-0.4123, 29.9283) and (-0.4634, 29.9677) .. (-0.549, 30.0451).. controls (-0.5767, 30.0695) and (-0.6045, 30.0937) .. (-0.6323, 30.118).. controls (-0.6461, 30.13) and (-0.6599, 30.1421) .. (-0.674, 30.1546).. controls (-0.7788, 30.2439) and (-0.8932, 30.3212) .. (-1.0054, 30.4006).. controls (-1.054, 30.4352) and (-1.1026, 30.4698) .. (-1.1512, 30.5044).. controls (-1.1832, 30.5272) and (-1.2152, 30.5499) .. (-1.2473, 30.5726).. controls (-1.3366, 30.636) and (-1.4233, 30.7018) .. (-1.5081, 30.771).. controls (-1.5045, 30.8176) and (-1.5045, 30.8176) .. (-1.4817, 30.8769).. controls (-1.415, 30.9279) and (-1.415, 30.9279) .. (-1.3279, 30.9794).. controls (-1.3125, 30.9885) and (-1.2971, 30.9977) .. (-1.2812, 31.0071).. controls (-1.1313, 31.0947) and (-0.9777, 31.1741) .. (-0.8202, 31.2473).. controls (-0.7998, 31.257) and (-0.7793, 31.2668) .. (-0.7583, 31.2769).. controls (-0.612, 31.3414) and (-0.4613, 31.3788) .. (-0.3059, 31.4143).. controls (-0.2744, 31.4216) and (-0.2744, 31.4216) .. (-0.2422, 31.4291).. controls (-0.0892, 31.4622) and (-0.0892, 31.4622) .. (0.0, 31.4325) -- cycle;
  \path[fill=c373435,shift={(12.7265, -9.7631)}] (0.0, 31.4325).. controls (0.303, 31.386) and (0.5704, 31.1017) .. (0.7491, 30.8686).. controls (0.9847, 30.5233) and (1.0565, 30.1612) .. (0.9799, 29.7508).. controls (0.8993, 29.3884) and (0.7212, 29.0409) .. (0.4283, 28.8065).. controls (0.1149, 28.6345) and (0.1149, 28.6345) .. (-0.0529, 28.6808).. controls (-0.0711, 28.7266) and (-0.0711, 28.7266) .. (-0.0794, 28.7867).. controls (-0.048, 28.8409) and (-0.048, 28.8409) .. (0.0, 28.9008).. controls (0.3172, 29.3315) and (0.4299, 29.8269) .. (0.3627, 30.3558).. controls (0.3071, 30.6919) and (0.1692, 30.9964) .. (0.0132, 31.2969).. controls (0.0001, 31.3242) and (-0.013, 31.3515) .. (-0.0265, 31.3796).. controls (-0.0177, 31.397) and (-0.009, 31.4145) .. (0.0, 31.4325) -- cycle;
  \end{scope}
          }
}

\pgfkeys{
  /zebra/.cd,
  globalscale/.store in=\globalscale,
  zebracolor/.store in=\zebracolor,
  zebracolor=BrownLine,
  globalscale=1,
}

\node[rectangle,draw=BrownLine,line width=1pt,fill=BrownLine!10,
minimum width=35mm,minimum height=30mm](ZEB){};
%
\begin{scope}[local bounding box=ZEBRA,shift={($(ZEB)+(-1.3,-1.45)$)}]
\pic {zebra={globalscale=0.09}};
\node[rectangle,draw=red,minimum width=8mm,minimum height=6mm,line width=1.5pt](REC1)
at($(ZEB.80)!0.47!(ZEB.280)$){};
\draw[Line,-latex](REC1.south)--++(270:2)node[below](KE){卷积核};
\end{scope}
%
\begin{scope}[local bounding box=CHANEL1,shift={($(ZEB)+(3.3,0.2)$)}]
\foreach \i in {1,2,3} {
\pic at ({\i*0.1}, {-0.1*\i}) {channel={scalefac=1.5,picname=\i-CH1}};
}
\end{scope}
%
\begin{scope}[local bounding box=CHANEL2,shift={($(CHANEL1)+(2.6,0.2)$)}]
\foreach \i in {1,2,3,4,5} {
\pic at ({\i*0.1}, {-0.1*\i}) {channel={scalefac=1.15,picname=\i-CH2}};
}
\end{scope}
%
\begin{scope}[local bounding box=CHANEL3,shift={($(CHANEL2)+(2.2,0.4)$)}]
\foreach \i in {1,...,8} {
\pic at ({\i*0.1}, {-0.1*\i}) {channel={scalefac=1.0,picname=\i-CH3}};
}
\end{scope}
\begin{scope}[local bounding box=CHANEL4,shift={($(CHANEL3)+(1.6,2.0)$)}]
\foreach \i in {1,...,10} {
\pic at ({\i*0.3}, {-0.3*\i}) {channel={scalefac=0.75,picname=\i-CH4}};
}
\end{scope}
\begin{scope}[local bounding box=CHANEL5,shift={($(CHANEL4)+(2.8,3.5)$)}]
\foreach \i in {1,...,11} {
\pic at ({\i*0}, {-0.6*\i}) {channel={scalefac=0.3,picname=\i-CH5}};
}
\end{scope}
%%%%
%11 neurons
\begin{scope}[local bounding box=CIRCLES,shift={($(CHANEL4)+(4.3,0)$)}]
\foreach \i in {1,...,11} {
  \pgfmathsetmacro{\y}{(6-\i)*0.8}
  \pic at (0,\y) {circles={channelcolor=VioletLine,picname=1CI\i,}};
}
%2row -7 neurons
\foreach \j in {1,...,7} {
  \pgfmathsetmacro{\y}{(4-\j)*0.8 + 0}
  \pic at (2.2,\y) {circles={channelcolor=VioletLine,picname=2CI\j}};
}
%3row -7 neurons
\foreach \j in {1,...,5} {
  \pgfmathsetmacro{\y}{(3-\j)*0.8 + 0}
  \pic at (4.0,\y) {circles={channelcolor=VioletLine,picname=3CI\j}};
}
%4row -7 neurons
\foreach \j in {1,...,3} {
  \pgfmathsetmacro{\y}{(2-\j)*0.8 + 0}
  \pic at (5.5,\y) {circles={channelcolor=VioletLine,picname=4CI\j}};
}
%
\foreach \i in {1,...,11}{
\draw[Line](\i-CH5)--(1CI\i);
}
\foreach \i in {1,...,11}{
  \foreach \j in {1,...,7}{
\draw[Line](1CI\i)--(2CI\j);
}}
\foreach \i in {1,...,7}{
  \foreach \j in {1,...,5}{
\draw[Line](2CI\i)--(3CI\j);
}}

\foreach \i in {1,...,5}{
  \foreach \j in {1,...,3}{
\draw[Line](3CI\i)--(4CI\j);
}}
\end{scope}
\node[rectangle,draw=GreenLine,line width=1pt,fill=GreenL,
minimum width=46,minimum height=80](OU)at($(CIRCLES.east)+(1.1,0)$){};
\draw[LineD](4CI1)--node[above]{0.2}($(OU.north east)!0.25!(OU.south east)$)coordinate(HO);
\draw[LineD](4CI2)--node[above]{0.7}($(OU.north east)!0.5!(OU.south east)$)coordinate(ZE);
\draw[LineD](4CI3)--node[above]{0.1}($(OU.north east)!0.75!(OU.south east)$)coordinate(DO);
\draw[thick](HO)--++(0:0.2)node[right](HORSE){马};
\draw[thick](ZE)--++(0:0.2)node[right]{斑马};
\draw[thick](DO)--++(0:0.2)node[right]{狗};
\node[above=6pt of OU]{输出};
\node[below=6pt of OU,align=center]{SoftMax 激活\\ 函数};
%\draw[](ZEB.80)--(ZEB.280);
%%%
\node[rectangle,draw=red,minimum width=5mm,minimum height=6mm,line width=1.5pt](REC2)
at($(3-CH1.80)!0.27!(3-CH1.280)$){};
\node[rectangle,draw=red,minimum width=5mm,minimum height=6mm,line width=1.5pt](REC3)
at($(5-CH2.70)!0.7!(5-CH2.290)$){};
\node[rectangle,draw=red,minimum width=5mm,minimum height=6mm,line width=1.5pt](REC4)
at($(8-CH3.70)!0.3!(8-CH3.290)$){};
\draw[LineD](REC1.north east)--($(3-CH1.100)!0.7!(3-CH1.260)$);
\draw[LineD](REC1.south east)--($(3-CH1.100)!0.7!(3-CH1.260)$);
\draw[LineD](REC2.north east)--($(5-CH2.100)!0.3!(5-CH2.260)$);
\draw[LineD](REC2.south east)--($(5-CH2.100)!0.3!(5-CH2.260)$);
\draw[LineD](REC3.north east)--($(8-CH3.100)!0.3!(8-CH3.260)$);
\draw[LineD](REC3.south east)--($(8-CH3.100)!0.3!(8-CH3.260)$);
\draw[LineD](REC4.north east)--($(10-CH4.100)!0.3!(10-CH4.260)$);
\draw[LineD](REC4.south east)--($(10-CH4.100)!0.3!(10-CH4.260)$);
\draw[LineD](1-CH4.north west)--(1-CH5.north west);
\draw[LineD](1-CH4.north east)--(1-CH5.north west);
\draw[LineD](10-CH4.south west)--(11-CH5.south west);
\draw[LineD](10-CH4.south east)--(11-CH5.south west);
%Text
\node[below=6pt of 3-CH1,align=center]{卷积\\ + \\ ReLU};
\node[below=10pt of 5-CH2,align=center]{卷积\\ + \\ ReLU};
\node[below=10pt of 8-CH3,align=center]{卷积\\ + \\ ReLU};
\node[below=4pt of 11-CH5,align=center]{展平\\ 层};
\path[red](3-CH1.south west)--++(270:2.3)coordinate(FM1)-|coordinate(FM2)(10-CH4.south east);
\path[red](ZEB.south west)--++(270:3.8)coordinate(FE1)-|coordinate(FE2)(11-CH5.south west);
\path[red](ZEB.south west)--++(270:3.8)-|coordinate(CL1)(11-CH5.south east);
\path[red](ZEB.south west)--++(270:3.8)-|coordinate(CL2)(4CI1.east);
\path[red](ZEB.south west)--++(270:3.8)-|coordinate(PD1)(OU.south west);
\path[red](ZEB.south west)--++(270:3.8)-|coordinate(PD2)(HORSE.east);
\path[red](1CI11.south)--++(270:0.1)coordinate(FCL1)-|coordinate(FCL2)(4CI3.south);
%
\draw[latex-latex,line width=0.75pt](FM1)--node[above]{特征图}(FM2);
\draw[BlueLine,decoration={brace,amplitude=9pt,mirror},decorate,line width=0.75pt]([yshift=0mm]FE1)--([yshift=0mm]FE2)
 node [midway,below=4mm,black] {特征提取};
\draw[BlueLine,decoration={brace,amplitude=9pt,mirror},decorate,line width=0.75pt]([yshift=0mm]CL1)--([yshift=0mm]CL2)
 node [midway,below=4mm,black] {分类};
\draw[BlueLine,decoration={brace,amplitude=9pt,mirror},decorate,line width=0.75pt]([yshift=0mm]PD1)--([yshift=0mm]PD2)
 node [midway,below=4mm,black] {概率分布};
 \draw[VioletLine,decoration={brace,amplitude=9pt,mirror},decorate,line width=0.75pt]([yshift=0mm]FCL1)--([yshift=0mm]FCL2)
 node [midway,below=3mm,black] {全连接层};
 %text above
\path[red](ZEB.north)--++(90:0.7)coordinate(IN)-|coordinate(PO1)(1-CH1.north east);
\path[red](ZEB.north)--++(90:0.7)-|coordinate(PO2)(1-CH2.north east);
\path[red](ZEB.north)--++(90:0.7)-|coordinate(PO3)(1-CH3.north east);
\node at(IN){输入};
\node at(PO1){池化};
\node at(PO2){池化};
\node at(PO3){池化};
\end{tikzpicture}
Figure 3: 空间特征提取:斑马图像经过重复的卷积、ReLU 和池化阶段,形成逐渐加深的特征图,随后经过展平、全连接层,最后通过 softmax 在马、斑马和狗三个类别之间进行分类。

这种分层组合出现在多个物理领域中:计算机视觉中,局部像素邻域形成轮廓;语音频谱图中,局部时频簇用于识别音素;体积断层成像中,连续体素块用于分离组织边界。这种架构之所以成功,并非因为它模仿了生物视觉,而是因为它契合了底层数据的组合结构。

在图像处理中,识别对象需要两项不同的计算保证。首先,架构必须在有界感受野内捕获局部几何基元。其次,由于对象无论出现在画面的哪个位置,其语义身份都保持不变,因此网络必须能够在任意坐标平移下识别这些基元。11 卷积网络通过结合局部卷积核与参数共享来满足这两项要求:在中间阶段强制实现平移等变性,同时通过池化使下游处理获得不变性 (LeCun et al. 1989; Krizhevsky et al. 2012)。12 这些由 LeCun13 (LeCun et al. 1989) 引入的架构约束,以结构化的空间模板运算取代了不受约束的稠密矩阵乘法。

LeCun, Yann, Bernhard Boser, John S. Denker, Donald Henderson, Richard E. Howard, Wayne Hubbard, and Lawrence D. Jackel. 1989. “Backpropagation Applied to Handwritten Zip Code Recognition.” Neural Computation 1 (4): 541–51. https://doi.org/10.1162/neco.1989.1.4.541.

算法结构

形式上,equation 3 通过在每个空间坐标处计算局部的跨通道点积,求得二维卷积层的前向传播结果: \[ \mathbf{H}^{(\ell)}_{i,j,k} = f\left(\sum_{m}\sum_{n}\sum_{c} \mathbf{W}^{(\ell)}_{m,n,c,k}\mathbf{H}^{(\ell-1)}_{i+m,j+n,c} + \mathbf{b}^{(\ell)}_k\right) \tag{3}\]

这里,\(\mathbf{H}^{(\ell)}_{i,j,k}\) 表示第 \(\ell\) 层输出通道 \(k\) 中空间位置 \((i,j)\) 处的激活值。三重求和遍历滤波器的各个维度:空间偏移 \((m,n)\) 覆盖局部卷积核窗口(定义了该层的局部感受野),14 而 \(c\) 遍历所有输入通道。张量 \(\mathbf{W}^{(\ell)}_{m,n,c,k}\) 存储连接通道 \(c\) 与通道 \(k\) 的卷积核权重,\(\mathbf{b}^{(\ell)}_k\) 则是各通道的偏置。由于卷积核权重 \(\mathbf{W}^{(\ell)}\) 不依赖于空间坐标 \((i,j)\),因此每个坐标都复用相同的滤波器参数。

卷积层通常使用较小的空间卷积核(\(3{\times}3\) 或 \(5{\times}5\)),以保持较小的参数存储占用,同时通过堆叠多层来扩大有效感受野。figure 4 中的滑动窗口机制展示了这一运算:滤波器在输入数组上移动,在每个有效坐标处计算乘加点积,从而生成输出特征图。交互式 CNN Explainer 工具 (Wang et al. 2021) 直观展示了这些堆叠的滑动窗口如何跨层提取各通道的激活模式。

Wang, Zijie J., Robert Turko, Omar Shaikh, Haekyu Park, Nilaksh Das, Fred Hohman, Minsuk Kahng, and Duen Horng Polo Chau. 2021. “CNN Explainer: Learning Convolutional Neural Networks with Interactive Visualization.” IEEE Transactions on Visualization and Computer Graphics 27 (2): 1396–406. https://doi.org/10.1109/tvcg.2020.3030418.
\scalebox{0.7}{%
\begin{tikzpicture}[x={(-1,-0.4)}, y={(0.8,0.8)}, line join=round,font=\sffamily]
\makeatletter
\newif\ifboxdashed
\boxdashedfalse % default: not dashed

\tikzset{
  box/.pic={
    \pgfkeys{/box/.cd,#1}
    \coordinate (origin) at (0,0);
    % intersection points
    \foreach \x in {0,...,\columns}{
      \foreach \y in {0,...,\rows}{
        \coordinate (pt-\x-\y\br) at ($ (origin) + \x*\cellsize*(1,0) + \y*\cellheight*(0,1) $);
      }
    }
    % Drawing cells
    \foreach \x in {0,...,\numexpr\columns-1}{
      \foreach \y in {0,...,\numexpr\rows-1}{
        \draw[fill=\ffill, line width=\linewidth, \ifboxdashed dashed\fi]
          (pt-\x-\y\br) --
          (pt-\the\numexpr\x+1\relax-\y\br) --
          (pt-\the\numexpr\x+1\relax-\the\numexpr\y+1\relax\br) --
          (pt-\x-\the\numexpr\y+1\relax\br) -- cycle;
      }
    }
  }
}

\pgfkeys{
  /box/.cd,
  cellsize/.store in=\cellsize,
  linewidth/.store in=\linewidth,
  cellheight/.store in=\cellheight,
  columns/.store in=\columns,
  rows/.store in=\rows,
  br/.store in=\br,
  ffill/.store in=\ffill,
  dashed/.code={\boxdashedtrue},
  columns=1,
  rows=3,
  br=A,
  ffill=red,
  cellsize=0.5pt,
  cellheight=0.5pt,
  linewidth=0.5pt
}
\makeatother

\pic at (0,0.66) {box={columns=5,rows=5,br=A,ffill=violet!20,cellsize=0.3pt,cellheight=0.3pt,linewidth=0.5pt}};
\pic at (0.3,0.96) {box={columns=1,rows=1,br=B,ffill=violet!50,cellsize=0.3pt,cellheight=0.3pt,linewidth=0.5pt}};

\pic at (1,-4) {box={columns=7,rows=7,br=C,ffill=none,linewidth=0.5pt,dashed}};
\pic at (2,-3) {box={columns=3,rows=3,br=E,ffill=orange,linewidth=0.35pt}};
 \draw[blue](pt-0-0B)--(pt-0-0E);
\draw[blue](pt-0-1B)--(pt-0-3E);
\draw[blue](pt-1-1B)--(pt-3-3E);
\draw[blue](pt-1-0B)--(pt-3-0E);
\pic at (0,0.66) {box={columns=5,rows=5,br=A,ffill=violet!20,cellsize=0.3pt,cellheight=0.3pt,linewidth=0.35pt}};
\pic at (0.3,0.96) {box={columns=1,rows=1,br=B,ffill=violet!70,cellsize=0.3pt,cellheight=0.3pt,linewidth=0.35pt}};
\end{tikzpicture}}
Figure 4: 卷积运算:虚线 \(7{\times}7\) 输入中的一个橙色 \(3{\times}3\) 感受野,映射到紫色 \(5{\times}5\) 有效卷积输出中的一个单元。将 \(3{\times}3\) 滤波器应用于该感受野时,计算每个输出值需要对每个输入通道执行 9 次乘加运算。对于 \(224{\times}224\) RGB 输入,参数共享将具有 150,528 个权重的稠密输入连接缩减为具有 27 个权重的局部滤波器,即权重数量的缩减倍数约为 5,575\(\times\),同时编码了平移等变性:同一个边缘检测器可在图像的任意位置工作。

将 CNN 应用于 \(28{\times}28\) 的 MNIST 图像,可以展示状态表示上的差异。每个卷积层都直接在二维网格上应用一组滤波器(例如,32 个大小为 \(3{\times}3\) 的滤波器),而不是将图像展平为破坏空间邻接关系的 784 元素向量。当步幅为 1,并通过填充保持边界尺寸时,该层输出一个保留空间网格的 \(28{\times}28{\times}32\) 激活张量。每个坐标都包含从其紧邻区域提取的 32 种不同特征测量值。

保留空间拓扑会改变执行单元访问内存的方式。卷积层并不像 MLP 那样为每个样本加载一次非共享权重矩阵,而是让输入特征图流经硬件寄存器,同时将紧凑的滤波器权重固定保留在快速片上 SRAM 或寄存器文件中。这种算术运算模式推动了 AI 加速器的存储层次优化,其中循环分块和并行通道归约可减轻高带宽内存(HBM)的流量压力。

平移等变性保证了这种数据复用模式:平移输入会使输出特征图发生相同的空间平移。对于系统工程,等变性确保计算调度和内存访问的几何模式在不同空间坐标处保持不变。

等变性和不变性决定了架构如何响应空间变换。如果对输入施加变换后,输出也按相同算子发生变换,则算子 \(f\) 对变换 \(\mathcal{T}\) 具有等变性(equation 4): \[ f(\mathcal{T}(\mathbf{x})) = \mathcal{T}(f(\mathbf{x})) \tag{4}\]

对于不受边界填充效应影响、步幅为 1 的卷积层,将输入平移向量 \(v = (v_1, v_2)\),会使生成的特征图恰好平移 \(v\)。空间坐标信息以确定性的方式在层中传播。相比之下,如果对输入施加变换后输出保持不变,则算子对 \(\mathcal{T}\) 具有不变性(equation 5): \[ f(\mathcal{T}(\mathbf{x})) = f(\mathbf{x}) \tag{5}\]

覆盖整张特征图的全局平均池化层 具有平移不变性:平移输入会改变激活值的空间位置,但对所有空间位置取平均会将坐标归并为一个标量,无论特征出现在哪里,该标量都相同。

这种数学上的区别决定了网络层次中哪些位置必须保持等变性,哪些位置应当引入不变性。目标检测和语义分割等任务要求等变性一直保持到最后一层:边界框坐标和逐像素掩码必须精确跟踪对象坐标。相比之下,分类任务要求中间特征提取器具有等变性,以保留相对空间关系(“眼睛在鼻子上方”),而最后几层则通过池化引入平移不变性,将空间坐标归并为类别概率向量。

对于输入 \(\mathbf{x}\) 和滤波器 \(\mathbf{w}\),离散二维卷积计算如下: \[ (\mathbf{x} * \mathbf{w})[i, j] = \sum_{m,n} \mathbf{w}[m, n] \cdot \mathbf{x}[i + m, j + n]. \] 施加平移 \(\mathcal{T}_v\)(其中 \((\mathcal{T}_v \mathbf{x})[i, j] = \mathbf{x}[i - v_1, j - v_2]\)),并重新索引求和,可得: \[ ((\mathcal{T}_v \mathbf{x}) * \mathbf{w})[i, j] = \sum_{m,n} \mathbf{w}[m, n] \cdot \mathbf{x}[i - v_1 + m, j - v_2 + n] = (\mathbf{x} * \mathbf{w})[i - v_1, j - v_2] = \mathcal{T}_v(\mathbf{x} * \mathbf{w})[i, j], \] 这证实了除边界条件影响外的平移等变性:\(f(\mathcal{T}_v \mathbf{x}) = \mathcal{T}_v(f(\mathbf{x}))\)。具有等变性 的卷积层保留坐标信息,而具有不变性的池化层则完全丢弃空间坐标。示例 1.4 通过显式矩阵运算验证了这种跟踪关系。

Example 1.4: 等变性:特征检测

设置:考虑一张第 3 列存在垂直边缘的 \(7{\times}7\) 图像: \[ \mathbf{x} = \begin{bmatrix} 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 \end{bmatrix} \]

垂直边缘检测滤波器: \[ \mathbf{w} = \begin{bmatrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{bmatrix} \]

对原始图像进行卷积:

输出特征图在滤波器从暗到亮过渡的位置(边缘左侧)呈现正激活值,在从亮到暗过渡的位置(右侧)呈现负激活值: \[ f(\mathbf{x}) = \begin{bmatrix} 3 & 0 & -3 & 0 & 0 \\ 3 & 0 & -3 & 0 & 0 \\ 3 & 0 & -3 & 0 & 0 \\ 3 & 0 & -3 & 0 & 0 \\ 3 & 0 & -3 & 0 & 0 \end{bmatrix} \]

平移后的输入(边缘移至第 5 列): \[ \mathcal{T}_2 \mathbf{x} = \begin{bmatrix} 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 \end{bmatrix} \]

对平移后的图像进行卷积: \[ f(\mathcal{T}_2 \mathbf{x}) = \begin{bmatrix} 0 & 0 & 3 & 0 & -3 \\ 0 & 0 & 3 & 0 & -3 \\ 0 & 0 & 3 & 0 & -3 \\ 0 & 0 & 3 & 0 & -3 \\ 0 & 0 & 3 & 0 & -3 \end{bmatrix} = \mathcal{T}_2(f(\mathbf{x})) \]

系统启示:特征激活的平移量与输入相同,体现了等变性。网络知道平移后图像中的边缘位于第 5 列,而不只是知道某处存在一条边缘。

参数效率是平移等变性最直接的系统层面影响。强制实行权重共享,可使参数容量与输入分辨率解耦。例如,使用 MLP 处理一张 \(224{\times}224\) RGB 图像时,每个隐藏神经元都需要连接全部 150,528 input pixels。采用 \(3{\times}3\) 滤波器的 CNN,每个滤波器仅需要 27 parameters,并在全部 \(224{\times}224\) 个空间位置上复用。这意味着每个特征检测器的参数量缩减倍数约为 5,575.1×。缩小参数存储占用,可以使模型权重常驻加速器 SRAM 或 L2 缓存,从而支持更大的批量大小,而不必溢出到外部 DRAM。

等变性所强制形成的计算规律性直接有利于硬件执行。由于每个空间坐标都执行相同的滑动窗口运算,这种计算模式可以直接映射到 SIMD 向量单元和脉动阵列。现代 GPU 和 TPU 利用这种统一结构:执行流水线在不同空间分块上发出相同的指令,不会产生控制流分歧。感受野之间的重叠意味着,相邻输出坐标会共享输入激活值,从而为共享内存缓存和算法层面的数据重组(例如 im2col 变换)创造机会,使硬件执行单元达到饱和利用。

等变性还能提高样本效率,降低训练流水线开销。当网络更新一个滤波器,使其能够在某个坐标识别某一特征时,参数共享可确保所有空间坐标同时获得识别该特征的能力。模型无需通过单独的训练样本来学习位于不同像素偏移处的相同特征,这起到了结构性数据增强的作用。这种样本效率减少了达到目标准确率所需的训练总迭代次数、数据集存储量以及主机到设备的 I/O 带宽。

Theorem 1.1: 群等变性的形式化表述
从群论角度看,卷积对平移的等变性是一般原理的一个实例。平移群 \((\mathbb{R}^2, +)\) 由所有二维平移构成,并且在复合运算下封闭(先平移 \(v\) 再平移 \(u\),等价于平移 \(v + u\))。卷积对该群具有等变性。近期研究将这一框架扩展到其他对称群。Cohen and Welling (2016) 提出了群等变 CNN,通过构造对旋转群具有等变性的滤波器来处理旋转和反射。这使模型能够在卫星图像或医学成像等方向不决定语义的任务中,学习具有旋转不变性的特征。

这一数学框架可以直接推广:对于作用于输入空间 \(X\) 和输出空间 \(Y\) 的群 \(G\),如果函数 \(f: X \to Y\) 满足下式,则称其具有 \(G\) 等变性: \[ f(g \cdot \mathbf{x}) = g \cdot f(\mathbf{x}) \quad \forall g \in G, \mathbf{x} \in X \]

标准 CNN 具有平移等变性,而旋转等变网络则将这一性质扩展到旋转群。由此可以推广出一条架构原则:应当将数据的对称性以等变性的形式嵌入架构。对于系统工程,识别数据对称性可直接为架构选择提供依据:具有更强对称性、约束更多的架构通常会产生更小的模型,而专门的等变性可能需要旋转卷积等自定义运算,这些运算需要硬件支持或高效的软件实现。

Cohen, Taco, and Max Welling. 2016. “Group Equivariant Convolutional Networks.” Proceedings of the 33rd International Conference on Machine Learning (ICML) 48: 2990–99.

实践中,实现约束往往会破坏完美的等变性。边界处的非对称填充 会引入边缘伪影,破坏严格的平移对称性。带步幅的下采样 会引入空间混叠,使输入中的单像素平移导致输出特征图中的子采样相位偏移。如果激活统计量在不同空间位置上的计算或应用方式不一致,批归一化层也会扰动空间等变性。现代生产网络接受这些偏差,因为步幅带来的计算节省和归一化带来的训练稳定性,超过了失去精确数学等变性所造成的损失。

Checkpoint 1.2: 空间归纳偏置

CNN 之所以成功,是因为它契合了图像数据的结构。请检查你是否理解其机制:

这些结构性质具体体现了 section 1.1 中引入的空间归纳偏置:通过将连接限制在局部邻域,并在所有坐标间共享参数,CNN 强制施加了视觉基元具有局部性和平移等变性这一先验。在整张特征图上复用相同的卷积核权重,相比稠密层可使参数存储量降低多个数量级,并将假设空间限制为保持几何结构的函数。

这种分层结构自然地实现了层次化表示学习 (Bengio et al. 2013)。早期层在较小的感受野内检测低层特征(边缘和颜色梯度),后续层则将这些基元组合为中间层次的纹理、对象部件和语义类别。堆叠卷积层会扩大有效感受野:对于固定的 \(K{\times}K\) 卷积核和单位步幅,感受野边长每层增加 \(K-1\) 个像素,而感受野面积按二次关系增长,直至覆盖整个输入维度。加速器执行这一不断扩展的层次结构的效率,取决于滑动窗口模板运算如何映射到并行执行流水线。

Bengio, Yoshua, Aaron Courville, and Pascal Vincent. 2013. “Representation Learning: A Review and New Perspectives.” IEEE Transactions on Pattern Analysis and Machine Intelligence 35 (8): 1798–828. https://doi.org/10.1109/tpami.2013.50.

计算映射

将数学卷积转化为硬件执行,需要弥合高层软件接口与芯片执行流水线之间的鸿沟。高层框架将卷积抽象为一次统一的层调用,如 listing 3 所示。在这一简洁 API 背后,底层运行时必须调度跨缓存层次的内存流量,并将滑动窗口模板运算转换为矩阵执行硬件上的操作。

Listing 3: 卷积层抽象:框架层面的卷积运算隐藏了滑动窗口计算的复杂性,通常将运算分派给 cuDNN 或 MKL,由其在内部处理 im2col 变换或直接卷积算法。
def conv_layer_spatial(input, kernel, bias):
    """Framework-level convolution.

    Single call dispatches to optimized kernel (often via im2col + GEMM).
    """
    # Convolution applies shared weights across all positions
    # For a 3x3 kernel on 28x28 input (padded): 9 MACs per position x 784 positions
    output = convolution(input, kernel) + bias
    return activation(output)

为揭示框架抽象所掩盖的计算机制,listing 4 详细展示了执行直接二维卷积所需的标准七重嵌套循环。这些循环可划分为三个结构层次:遍历样本的批次迭代、遍历特征图坐标 \((y, x)\) 的空间遍历,以及结合卷积核偏移 \((k_y, k_x)\)、沿输入和输出维度 \((C_{\text{in}}, C_{\text{out}})\) 进行的通道累加。遍历空间坐标和输出通道,就确定了相互独立的输出激活值所构成的网格。

Listing 4: 卷积计算的逻辑过程:七重嵌套循环揭示了 \(\mathcal{O}(B \times H_{\text{img}} \times W_{\text{img}} \times C_{\text{out}} \times K_h \times K_w \times C_{\text{in}})\) 的复杂度。尽管逻辑上正确,这种模式在硬件上的执行效率却很低;生产系统会将其转换为分块矩阵乘法。
def conv_layer_compute(input, kernel, bias):
    # Logical view of convolution (usually implemented via im2col +
    # GEMM)
    # Loop 1: Process each image in batch
    for image in range(batch_size):
        # Loop 2&3: Move across image spatially
        for y in range(height):
            for x in range(width):
                # Loop 4: Compute each output feature
                for out_channel in range(num_output_channels):
                    result = bias[out_channel]
                    # Loop 5&6: Move across kernel window
                    for ky in range(kernel_height):
                        for kx in range(kernel_width):
                            # Loop 7: Process each input feature
                            for in_channel in range(num_input_channels):
                                # ... MAC operations ...

最内层的三个循环在每个空间位置执行卷积核点积。对于每个输出激活值,卷积核都会对所有输入通道上的局部 \(3{\times}3\) 输入块进行计算。在现代硬件上直接执行这一嵌套循环会导致较差的缓存局部性和非合并的内存访问,因为相邻的空间迭代会通过跨步偏移访问相互重叠的输入块。

为避免跨步内存访问,cuDNN 和 oneDNN 等生产级库通常通过 im2col(图像转列)变换,将卷积降为矩阵运算。im2col 将每个感受野对应的输入块重新排列为输入矩阵中的一个连续列,从而将整个卷积重构为稠密通用矩阵乘法(GEMM)。这种转换以更大的内存占用为代价——在 DRAM 或 SRAM 中将重叠的输入像素最多复制 \(K^2\) 次——换取 GEMM 内核在结构上的规整性,使张量核心和脉动阵列能够满负荷运行。另一种方法是采用隐式 GEMM 技术,在寄存器文件中即时生成这些矩阵坐标,而不在内存中实际构建重复数据缓冲区。使用 \(3{\times}3\) 滤波器和 32 个输出通道时,每个输出坐标对每个输入通道仅需执行 9 次 MAC 运算,而作为参照的 MLP 层则需要 784 次 MAC 运算。滑动窗口在减少每个激活值所需运算量的同时,也引入了不同的数据复用模式,决定了数据在内存层次中的暂存方式。

系统层面的影响

section 1.3.3 中介绍的滑动窗口和 im2col 变换揭示了 CNN 如何计算;本节则揭示这种计算在内存、计算资源和数据移动方面的代价。这些代价取决于网络层深度、激活值的存活期,以及特征图是保留在 SRAM 缓存中还是溢出到 HBM。

内存需求

卷积层的内存消耗可分为两类不同的状态:静态滤波器参数和暂态特征图(激活值)。权重共享确保了参数存储保持紧凑:对于 ImageNet 输入,一个包含 64 个 \(3{\times}3\) 滤波器、作用于单个输入通道的卷积层,仅需 576 个参数。即便输入通道数达到 64,存储 36,864 个 FP32 权重也仅需约 147 KB,可以轻松放入片上 L2 或 L1 缓存。相比之下,中间特征图的规模随输入分辨率和通道深度增长:一个具有 64 个通道的 \(224{\times}224\) 特征图会实际生成 3.2M 个激活值(采用 FP32 时,批次中每个样本约占 12.8 MB)。训练期间,这些激活值必须保持驻留在内存中,以供反向传播计算梯度,因此,对于加速器上的深层 CNN,形成实际内存约束的是激活值内存,而非权重存储容量。

加速器通过分层缓存利用这种内存占用差异。CPU 将紧凑的滤波器权重保留在 L2/L3 缓存中,同时以流式方式处理激活张量。GPU 将滤波器权重和输入分块暂存于片上暂存 SRAM(共享内存)和寄存器文件中,在数千个空间坐标上复用已加载的权重,消除与片外 HBM 之间冗余的往返传输。支持这些缓存模式的硬件设计原理详见 硬件加速。

计算需求

计算卷积层需要在各个空间位置反复计算局部点积。对于使用 \(3{\times}3\) 滤波器和 64 个输出通道的 ImageNet 输入,计算单个空间位置时,每个输入通道需要执行 576 次乘加运算。在全部 50,176 个空间位置重复这一计算,使得每层的运算量达到数百万次。尽管每个空间模板涉及的参数少于稠密层,但空间上的重复计算会成倍增加浮点运算总量。

这种计算规整性为硬件并行化提供了丰富的机会。由于各个空间坐标相互独立,处理器可以同时沿多个轴并行执行任务:批次维度、空间坐标 \((x, y)\) 和输出通道。CPU 执行向量化 SIMD 指令15,在每个时钟周期计算多个空间位置的输出;GPU 则将线程束分派到数千条并发执行通道上。剪枝和通道稀疏化等改变这一计算特征的模型压缩技术将在 模型压缩 中讨论。

数据移动

卷积层数据移动的算术强度特征与 MLP 存在根本差异。在批次大小为 1 的全连接层中,每个加载的权重恰好只使用一次,算术强度的上限低于 1 FLOP/byte。在二维卷积中,每个 \(3{\times}3\) 滤波器权重都会在 \(224{\times}224\) 特征图的全部 50,176 个位置上复用。这种大规模权重复用提高了运算强度,使计算从受内存带宽限制的区域向受计算能力限制的上限移动。

系统挑战由加载权重转向暂存激活值。由于相邻空间感受野相互重叠,朴素的内存访问模式会将每个输入像素从内存中重复读取最多 \(K^2 = 9\) 次。运行时系统通过将计算划分为能够放入加速器 SRAM 的二维空间块,避免这种冗余的内存流量。输入分块一旦加载到共享内存,该分块上所有相互重叠的滤波器点积计算便可就地执行,从而摊薄 DRAM/HBM 传输成本,并充分利用每个滤波器权重的 50,176 次复用机会。

这些内存、计算和数据移动模式汇聚于一个模型:ResNet-50 架构。它是本章讨论受计算能力限制的视觉工作负载时所采用的参照模型。

Lighthouse 1.2: ResNet-50(视觉灯塔模型)

重要性:ResNet-50 是规整、以卷积为主的视觉工作负载的参照模型。其架构几乎完全由稠密卷积层组成,因此在 GPU 上具有高度规整性和较高的执行效率。在数据复用良好的批量执行条件下,ResNet-50 的性能通常受浮点运算吞吐量(FLOP/s)限制,因此是解释数据并行、量化和批处理策略的实用灯塔模型。Table 4 总结了其量化属性及其对系统的影响:

Table 4: ResNet-50 系统特征:视觉灯塔模型的量化属性及其对系统的影响。在批量卷积复用条件下,ResNet-50 具有较高的有效算术强度,通常受计算能力限制,因此张量核心上的峰值浮点运算吞吐量往往先于内存带宽成为性能上限。
属性 数值 系统影响
参数量 25.6M FP32 下模型大小为 102.4 MB;可轻松放入 GPU 显存。
每张图像的 FLOPs 8.2 GFLOP \((224{\times}224)\) \(3{\times}3\) 卷积是占比最大的单一内核类别,约占 MAC 运算的 48%。
约束 批处理时计算密集 当权重和激活值复用程度较高时,受峰值 FLOP/s 限制;小批次推理可能趋向受内存限制的区域。
瓶颈 浮点运算吞吐量 可最大限度地受益于专用矩阵单元(张量核心)。
特征 复用条件下有效算术强度较高 算术强度取决于批次大小、卷积算法,以及实际产生的内存流量。

ResNet-50 受计算能力限制的特征以充足的硬件资源为前提,然而,大多数推理运行在功率预算比数据中心 GPU 低三个数量级的设备上。MobileNetV2 表明,架构创新可以面向这类运行环境,以一小部分计算成本实现具有竞争力的准确率。

Lighthouse 1.3: MobileNetV2(效率灯塔模型)

重要性:MobileNetV2 代表了受延迟约束的边缘工作负载。其深度可分离卷积以通道混合能力换取速度,使其成为移动应用、嵌入式视觉和神经架构搜索(NAS,即对模型设计进行自动搜索)的实用基线。Table 5 总结了这一效率灯塔模型的量化属性:

Table 5: MobileNetV2 系统特征:效率灯塔模型的量化属性及其对系统的影响。MobileNetV2 的参数量和 FLOPs 均比 ResNet-50 小约一个数量级,其运算形态和算术强度使移动 CPU 上的单张图像推理延迟对算子分派开销和内存访问较为敏感。
属性 数值 系统影响
参数量 3.5M FP32 下为 14 MB;大小为 ResNet-50 的 1/7.3×。
每张图像的 FLOPs 600 MFLOP 在准确率相近的情况下,为 ResNet-50 的 1/13.7×。
约束 受延迟约束 优先考虑单张图像的推理速度。
瓶颈 开销/内存访问 算子分派和内存访问的成本可能超过实际计算。
特征 算术强度低 内存访问和控制逻辑比峰值 FLOP/s 更为关键。

ResNet-50 和 MobileNetV2 的特征揭示了一个关键的系统权衡:FLOPs 降至原来的 1/13.7×,并不意味着模型运行速度就会自动提高到原来的 13.7×。运算量的减少能否转化为实际运行时间的缩短,取决于算术强度、算子分派开销以及硬件的 Roofline 平衡。在面向高算术强度设计的数据中心 GPU 上,MobileNetV2 往往只能获得有限的加速,因为其碎片化的逐通道运算未能充分利用张量核心。

深度可分离卷积和剪枝(移除冗余权重或通道)等架构效率优化技术会改变这种硬件映射的平衡,详见 模型压缩。硬件加速 讨论处理器架构如何在硬件中利用这些空间数据复用模式。观点 1.1 探讨了将 FLOP 数量直接与执行延迟关联起来的核心谬误。

Systems Perspective 1.1: 误解:FLOPs 等同于速度
谬误:“MobileNetV2 的 FLOPs 为 ResNet-50 的 1/13.7×,所以它的运行速度一定是 ResNet-50 的 13.7×。”

辨析:在某些高端 GPU 上,尽管 MobileNetV2 的运算量少得多,其运行速度仍可能慢于 ResNet-50。MobileNetV2 的深度可分离卷积算术强度较低:相对于计算量,它们需要移动更多数据。针对稠密矩阵运算优化的 GPU 在执行这些内核时,可能无法充分利用其计算单元。FLOPs 衡量的是工作量;吞吐量则取决于这些工作映射到硬件的效果。这种硬件与模型架构不匹配的问题,将在 section 1.11 中作为一种普遍谬误再次讨论。

高效架构:关键词检测

section 1.3.4 中的系统影响分析假设采用具有完整卷积的标准 CNN 架构。标准卷积的计算复杂度为 \(\mathcal{O}(N \times K^2 \times C_{\text{in}} \times C_{\text{out}})\),这一计算量超出了始终在线的边缘设备严格的能耗预算。为弥合这一差距,深度可分离 CNN(DS-CNN) 等高效架构将标准卷积分解为两个不同的操作。这种因式分解由 Sifre 在特征提取的研究中提出 (Sifre and Mallat 2014),并通过 MobileNet 得到普及 (Howard et al. 2017),它将空间滤波与跨通道组合解耦。逐通道卷积 独立地对每个输入通道应用滤波器(\(K \times K \times C_{\text{in}}\) 个参数),而逐点卷积 使用 \(1{\times}1\) 卷积将通道投影到输出维度(\(1 \times 1 \times C_{\text{in}} \times C_{\text{out}}\) 个参数)。这种分解将参数量和 FLOPs 降至标准卷积的约 \(\frac{1}{C_{\text{out}}} + \frac{1}{K^2}\)(即约缩减 \(K^2 \times\);对于 \(C_{\text{out}}\) 较大的 \(3 \times 3\) 滤波器,约缩减 8–9\(\times\)),使资源受限的微控制器能够实现实时执行。在关键词检测中,连续的一维音频流通过短时傅里叶变换预处理为二维时频谱图(或梅尔频率倒谱系数),使二维卷积核能够沿时间和频率单元滑动,以检测声学音素特征。

Sifre, Laurent, and Stéphane Mallat. 2014. “Rigid-Motion Scattering for Image Classification.” arXiv Preprint arXiv:1403.1687, ahead of print. https://doi.org/10.48550/arXiv.1403.1687.
Howard, A. G., M. Zhu, B. Chen, D. Kalenichenko, W. Wang, T. Weyand, M. Andreetto, and H. Adam. 2017. “MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications.” CoRR abs/1704.04861.

关键词检测工作负载是这一边缘效率范式的典型实例。

Lighthouse 1.4: KWS(TinyML 灯塔案例)
重要性:关键词检测模型(如 DS-CNN)代表了整个应用谱系中受功耗约束的一端。这些模型用于智能门铃等始终在线的应用,只有在音频触发后才唤醒更大型的视觉处理流水线,因此必须在功耗预算仅为毫瓦级的微控制器上运行。

KWS 迫使工程师精打细算每一个字节和每一个时钟周期。它是极致量化(INT8/INT4,详见 模型压缩)和专用架构原语(深度可分离卷积)的灯塔案例,这些技术以理论表征能力为代价,换取每瓦功耗下的最高效率。

从 ResNet-50 计算密集的标准卷积,到 MobileNet 的深度可分离变体,再到 KWS 的微功耗部署,CNN 展示了架构约束如何将数据结构转化为硬件效率。通过使计算模式与空间局部性和平移等变性相匹配,这些模型最大限度地提高算术强度,并尽量减少参数存储。然而,当数据关系按时间顺序而非几何关系组织时,卷积算子的一项基本假设——空间邻近性决定特征相关性——便不再成立。当输入构成序列流,且未来状态依赖于任意久远的历史上下文时,滑动的空间模板若不将卷积核扩展到难以管理的规模,就无法捕获时间依赖关系。处理此类数据需要围绕序列状态演化设计的架构。

RNN:序列模式处理

卷积网络利用的是空间结构,其中物理邻近性决定统计相关性。许多现实世界的信号则呈现时间结构,其含义由序列顺序和历史上下文决定。处理序列需要能够跨时间步维持持久状态的架构。

Definition 1.4: 循环神经网络

循环神经网络(RNN) 是一种序列处理架构,它维持一个在每个时间步更新的隐藏状态 \(\mathbf{h}_t = f(\mathbf{h}_{t-1}, \mathbf{x}_t)\),编码了这样一种假设:当前输出通过这一固定大小的状态向量依赖于此前的所有输入。

  1. 意义:固定大小的状态使推理内存保持为 \(\mathcal{O}(1)\),与序列长度无关(处理含 10,000 个词元的序列所需的内存与处理含 10 个词元的序列相同),但顺序更新规则形成了顺序执行瓶颈,所有 \(S\) 个步骤都必须依次执行,直接增加了机器学习系统铁律中的 \(L_{\text{lat}}\) 项,并使 RNN 在训练期间无法利用 GPU 在时间维度上的并行性。
  2. 区别:注意力机制同时访问完整的词元历史,并在处理完整序列时显式生成一个 \(\mathcal{O}(S^2)\) 的分数矩阵;与之不同,RNN 将历史压缩为一个瓶颈状态,这意味着梯度信号必须反向传播经过全部 \(S\) 个步骤——由此产生 \(\partial \mathcal{L} / \partial \mathbf{h}_0 \propto \prod_{t=1}^{S} \partial \mathbf{h}_t / \partial \mathbf{h}_{t-1}\),即 \(S\) 个雅可比矩阵的乘积,它会随序列长度呈指数级消失或爆炸。
  3. 常见误区:一种常见误解是 RNN 已经过时。对于资源受限硬件上的流式推理,例如微控制器上的关键词检测,\(\mathcal{O}(S^2)\) 的注意力内存开销高得难以承受,而 RNN 的 \(\mathcal{O}(1)\) 状态大小仍使其成为从系统角度看合理的选择。

随着序列长度增加,状态内存保持不变,而串行延迟持续上升。

RNN 的状态内存保持固定,但延迟随序列长度增加。

前馈架构和标准 CNN 独立处理输入,或将上下文限制在固定的空间感受野内。然而,在序列领域,依赖关系跨越的时间距离可变,而且往往没有上限。要扩展卷积感受野以覆盖长序列,就需要堆叠数十层网络或应用空洞卷积核;无论中间词元是否包含相关信息,这两种方法都会增加参数量和中间激活存储量。

从简单循环网络到长短期记忆(LSTM)网络等门控变体 (Elman 1990; Hochreiter and Schmidhuber 1997),循环架构通过引入时间归纳偏置来应对这一约束:执行顺序编码因果方向,历史则被压缩为循环传递的状态。网络不再孤立地处理每个输入向量,而是在连续时间步之间传递内部状态向量。这种归纳偏置确立了一项明确的工程权衡:它在固定内存预算内提供可变长度的时间上下文,但也引入了循环携带的数据依赖,使并行加速器硬件上的执行串行化。

Elman, Jeffrey L. 1990. “Finding Structure in Time.” Cognitive Science 14 (2): 179–211. https://doi.org/10.1207/s15516709cog1402_1.

模式处理需求

在序列模式处理中,对传入词元的解释取决于此前的序列。例如,“bank”这样的多义词无法孤立地消歧:“river bank”指地理意义上的河岸,而“bank account”指金融机构。仅凭词本身不足以确定含义;其语义角色由前文上下文确定。声学波形和遥测时间序列也具有相同的性质:如果没有跨越多个频率和时间尺度的历史上下文,单个样本便存在歧义。

具有这种结构的数据对底层模型提出了三项具体要求:

  1. 可变长度输入接收:到达的序列具有不同的长度 \(S\),因而无法使用要求静态输入形状的固定维度权重张量。
  2. 上下文持久性:模型必须在任意时间间隔内保留有信息价值的历史信号,而无需显式设置窗口。
  3. 连续状态更新:随着每个新词元到达,内部表征必须动态更新,在整合新证据的同时丢弃过时或含噪声的历史信息。

MLP 无法满足这些要求,因为其输入层维度在编译时静态固定,需要通过零填充或截断来适配一个固定的最大序列长度。CNN 通过静态滑动窗口处理输入,要求感受野随网络深度线性或指数增长。专为序列模式处理构建的架构必须将状态持久性作为其数据流的固有属性。

算法结构

为满足 section 1.4.1 中的要求,循环神经网络在计算图中引入有向环。RNN 不再通过前馈层直接将输入映射为输出,而是维持一个持久向量——隐藏状态——并在每个时间步对其进行迭代更新。隐藏状态充当内部寄存器,概括过去的观测,为未来的预测提供上下文。

equation 6 中的基本状态转移通过组合传入的词元向量 \(\mathbf{x}_t\) 与前一状态 \(\mathbf{h}_{t-1}\),计算当前隐藏状态 \(\mathbf{h}_t\): \[ \mathbf{h}_t = f(\mathbf{W}_{\text{hh}}\mathbf{h}_{t-1} + \mathbf{W}_{\text{hx}}\mathbf{x}_t + \mathbf{b}_h) \tag{6}\] 其中,\(\mathbf{h}_t\) 表示时刻 \(t\) 的隐藏状态,\(\mathbf{x}_t\) 表示时刻 \(t\) 的输入,\(\mathbf{W}_{\text{hh}}\) 包含循环权重,\(\mathbf{W}_{\text{hx}}\) 包含输入权重,\(\mathbf{b}_h\) 是隐藏状态偏置向量,\(f\) 是激活函数。该方程使用列向量;后续代码清单使用行优先的批量张量,因此权重乘法出现在右侧。比较 figure 5 的左右两图:左图展示紧凑的循环回路,右图将其沿时间步展开,明确呈现这种递归产生的时间依赖关系。

\begin{tikzpicture}[line join=round,font=\large\sffamily]
\tikzset{%
Line/.style={line width=0.95pt,black!60,text=black}
}
\def\radius{7mm}
\def\di{1.4}
\foreach \x/\i/\f in {0/1/$\mathbf{h}$,5/2/$\mathbf{h}_{t-1}$,9/3/$\mathbf{h}_t$,13/4/$\mathbf{h}_{t+1}$}{
\coordinate (2ball-\i) at  (\di*\x,0);
\fill[fill=mygreen!50] (\di*\x,0) circle (\radius)node[]{\f};
}

\def\radiuss{6.0mm}
\def\du{3.1}
\foreach \x/\i/\f in {0/1/$\mathbf{y}$,5/2/$\mathbf{y}_{t-1}$,9/3/$\mathbf{y}_t$,13/4/$\mathbf{y}_{t+1}$}{
\coordinate (1ball-\i) at  (\di*\x,\du);
\fill[fill=myorange!50] (\di*\x,\du) circle (\radiuss)node[]{\f};
}

\foreach \x/\i/\f in {0/1/$\mathbf{x}$,5/2/$\mathbf{x}_{t-1}$,9/3/$\mathbf{x}_t$,13/4/$\mathbf{x}_{t+1}$}{
\coordinate (3ball-\i) at  (\di*\x,-0.9*\du);
\fill[fill=mypurple!50] (\di*\x,-0.9*\du) circle (\radiuss)node[]{\f};
}

\foreach \x/\f in {1/$\mathbf{W}_{\text{hx}}$,2/$\mathbf{W}_{\text{hx}}$,3/$\mathbf{W}_{\text{hx}}$,4/$\mathbf{W}_{\text{hx}}$}{
    \edef\from{3ball-\x}
    \edef\to{2ball-\x}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radiuss) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[Line,-{Latex[length=3.0mm]}] (from) --node[fill=white,pos=0.42]{\f} (to);
 }

\foreach \x/\f in {1/$\mathbf{W}_{\text{yh}}$,2/$\mathbf{W}_{\text{yh}}$,3/$\mathbf{W}_{\text{yh}}$,4/$\mathbf{W}_{\text{yh}}$}{
    \edef\from{2ball-\x}
    \edef\to{1ball-\x}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radiuss) $);
  \draw[Line,-{Latex[length=3.0mm]}] (from) --node[fill=white,pos=0.5]{\f} (to);
 }

\foreach \x/\f in {2/$\mathbf{W}_{\text{hh}}$,3/$\mathbf{W}_{\text{hh}}$}{
\pgfmathtruncatemacro{\newX}{\x + 1} %
    \edef\from{2ball-\x}
    \edef\to{2ball-\newX}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[Line,-{Latex[length=3.0mm]}] (from) --node[fill=white]{\f} (to);
 }

\draw[Line,-{Latex[length=3.0mm]},shorten <=6.96mm] (2ball-4)--node[fill=white,pos=0.6,inner sep=0.5pt]{$\mathbf{W}_{\text{hh}}$}++(0:2.25);
\draw[Line,-{Latex[length=3.0mm]},shorten <=6.96mm,shorten >=6.96mm] (2ball-1)--++(0:1.2)coordinate(A)--++(90:1)--
node[fill=white,pos=0.50,inner sep=1pt]{$\mathbf{W}_{\text{hh}}$}++(180:2.5)|-(2ball-1);

\node[single arrow, draw=none, fill=cyan!50, anchor=west,
      minimum width = 20pt, single arrow head extend=3pt,
      minimum height=7mm](AR)at($(A)+(0.1,0)$){\small 展开};
\draw[Line,-{Latex[length=3.0mm]},shorten >=6.96mm] (AR)--node[fill=white,pos=0.3,inner sep=0.5pt]{$\mathbf{W}_{\text{hh}}$}(2ball-2);
\end{tikzpicture}
Figure 5: 循环神经网络展开:左图展示紧凑的循环回路;右图将其沿时间步展开。三个权重矩阵在所有步骤之间共享:\(\mathbf{W}_{\text{hx}}\)(输入到隐藏状态)、\(\mathbf{W}_{\text{hh}}\)(隐藏状态到隐藏状态)和 \(\mathbf{W}_{\text{yh}}\)(隐藏状态到输出)。这些矩阵在每个步骤中重复使用,因此参数量与序列长度无关。对于 128 维隐藏状态和 100 维输入,每个时间步的循环连接需要 16,384 次 MAC,输入投影还需要 12,800 次 MAC。

将循环回路沿 \(S\) 个步骤展开,可以揭示递归的算法特性。参数量与序列长度 \(S\) 无关,因为权重矩阵 \(\mathbf{W}_{\text{hh}}\) 和 \(\mathbf{W}_{\text{hx}}\) 在所有时间步之间共享。然而,跨时间共享权重会形成循环携带的依赖关系:只有在步骤 \(t-1\) 完成并产生 \(\mathbf{h}_{t-1}\) 后,步骤 \(t\) 才能计算 \(\mathbf{h}_t\)。这种依赖形成了一条长度为 \(\mathcal{O}(S)\) 的串行操作关键路径,使硬件加速器无法沿序列维度并行执行。

这种顺序结构使推理和训练具有根本不同的内存特性。在流式推理期间,RNN 每次计算一个步骤,丢弃此前的原始输入,仅保留当前隐藏状态。无论序列包含 10 个还是 10,000 个步骤,状态内存开销始终严格保持为 \(\mathcal{O}(d_{\text{hidden}})\)。相比之下,通过时间反向传播(BPTT) 进行训练时,需要沿长度为 \(S\) 的整个序列展开计算图。通过链式法则计算梯度,需要计算所有中间状态转移的雅可比矩阵乘积: \[ \frac{\partial \mathcal{L}}{\partial \mathbf{h}_0} = \frac{\partial \mathcal{L}}{\partial \mathbf{h}_S} \prod_{t=1}^{S} \frac{\partial \mathbf{h}_t}{\partial \mathbf{h}_{t-1}} \] 为计算这些雅可比矩阵乘积,训练引擎必须将中间激活 \(\mathbf{h}_1, \mathbf{h}_2, \dots, \mathbf{h}_S\) 保留在加速器内存中。因此,BPTT 将 \(\mathcal{O}(d_{\text{hidden}})\) 的运行时状态转化为训练期间 \(\mathcal{O}(S \cdot d_{\text{hidden}})\) 的内存占用。此外,反复乘以 \(\mathbf{W}_{\text{hh}}\) 会使梯度在较长时间跨度内呈指数级消失或爆炸,从而限制简单 RNN 的有效上下文窗口。循环权重矩阵通常包含对时间依赖关系贡献甚微的连接,因此可以通过 模型压缩 中介绍的方法进行显著压缩。

计算映射

将循环方程转化为硬件执行,可以揭示数学抽象如何映射到加速器内核、内存层次结构和循环嵌套。卷积层利用空间局部性以及跨分块的权重复用(section 1.1),而循环步骤则分解为受数据流串行化约束的矩阵向量或矩阵矩阵乘法。

Listing 5 使用框架级矩阵操作展示了单个时间步的机制:将前一隐藏状态与当前输入组合,加上偏置,再应用激活函数以产生下一隐藏状态。代码有意仅涵盖一个步骤,因为系统开销的关键并不在于步骤本身,而在于阻碍跨时间并行执行的依赖链。

Listing 5: RNN 层抽象:框架级实现,在每个时间步组合两次矩阵乘法 \(\mathbf{h}_{t-1}\mathbf{W}_{\text{hh}}\) 和 \(\mathbf{x}_t\mathbf{W}_{\text{hx}}\)。对于 128 维隐藏状态和 100 维输入,每个步骤需要 16,384 + 12,800 = 29,184 次 MAC,但顺序依赖阻碍了跨时间的并行执行。
def rnn_layer_step(x_t, h_prev, W_hh, W_hx, b):
    # x_t: input at time t (batch_size × input_dim)
    # h_prev: previous hidden state (batch_size × hidden_dim)
    # W_hh: recurrent weights (hidden_dim × hidden_dim)
    # W_hx: input weights (input_dim × hidden_dim)
    h_t = activation(matmul(h_prev, W_hh) + matmul(x_t, W_hx) + b)
    return h_t

在框架层面,rnn_layer_step 将底层循环结构和内存流量隐藏在高层矩阵乘法(matmul)之后。在硬件上,计算该步骤需要在内存层次结构中移动权重和激活。为看清执行在何处串行化、何处仍存在并行性,listing 6 将矩阵操作展开为显式循环嵌套,直至标量乘加操作。

Listing 6: RNN 层计算:嵌套循环揭示了顺序依赖结构。循环 1 支持批次并行,但循环 2–3 必须在循环 4 的激活操作之前完成;更关键的是,每个时间步都依赖前一步的输出,形成 \(\mathcal{O}(S)\) 的顺序执行深度,使 GPU 无法沿时间维度并行执行。
def rnn_layer_compute(x_t, h_prev, W_hh, W_hx, b):
    # Initialize next hidden state
    h_t = np.zeros_like(h_prev)

    # Loop 1: Process each sequence in the batch
    for batch in range(batch_size):
        # Loop 2: Compute recurrent contribution (h_prev × W_hh)
        for i in range(hidden_dim):
            for j in range(hidden_dim):
                h_t[batch, i] += h_prev[batch, j] * W_hh[j, i]

        # Loop 3: Compute input contribution (x_t × W_hx)
        for i in range(hidden_dim):
            for j in range(input_dim):
                h_t[batch, i] += x_t[batch, j] * W_hx[j, i]

        # Loop 4: Add bias and apply activation
        for i in range(hidden_dim):
            h_t[batch, i] = activation(h_t[batch, i] + b[i])

    return h_t

循环结构揭示了循环执行的并发边界。循环 1 表明,批次中的各个实例完全独立:同一批次内的序列可以在加速器核心之间并行执行,彼此互不干扰。在每个批次实例内部,循环 2 和循环 3 执行循环变换(\(\mathbf{h}_{t-1}\mathbf{W}_{\text{hh}}\))和输入投影(\(\mathbf{x}_t\mathbf{W}_{\text{hx}}\))。这两项归约都必须完成全部累加,循环 4 才能逐元素加上偏置并应用激活函数,产生 \(\mathbf{h}_t\)。

对于输入维度为 100、隐藏状态维度为 128 的情况,每个步骤执行两次矩阵乘法:一次 \(100{\times}128\) 的输入投影和一次 \(128{\times}128\) 的循环变换。当批大小较大(\(B \gg 1\))时,这些操作以通用矩阵矩阵乘法(GEMM)的形式执行,从内存加载的权重在全部 \(B\) 个样本之间复用,从而实现较高的算术强度。当批大小较小(\(B=1\),这是实时流式推理的典型情况)时,这些操作退化为矩阵向量乘法(GEMV)。在 GEMV 中,每个权重参数都必须从内存中读取,才能执行一次乘加,这使算术强度降至 \(\approx 1\) FLOP/byte,并使加速器计算单元因数据供给不足而闲置。

系统影响

循环架构施加了一项严格的物理约束:顺序依赖。对于 MLP 和 CNN,硬件可以沿神经元、通道和空间像素并行执行;与之不同,RNN 无法沿序列维度并行执行。更新 \(\mathbf{h}_t = \tanh(\mathbf{W}_{\text{hh}}\mathbf{h}_{t-1} + \mathbf{W}_{\text{hx}}\mathbf{x}_t)\) 确立了严格的顺序:只有在步骤 \(t-1\) 完成并写出其输出后,时间步 \(t\) 才能开始。对于长度为 \(S = 1{,}000\) 的输入序列,系统必须依次启动 \(1{,}000\) 次矩阵乘法。提升硬件计算能力或内存带宽可以加速各个步骤,但根据阿姆达尔定律,延迟受串行化关键路径的约束。因此,并行扩展被严格限制在批次维度。

在推理期间,循环网络具有出色的内存效率。由于循环状态将历史信息压缩为固定大小的向量 \(\mathbf{h}_t\),推理状态的内存占用按 \(\mathcal{O}(d_{\text{hidden}})\) 缩放(例如,512 维 FP32 状态占用 2 KB),无论序列长度 \(S\) 为 10 个还是 10,000 个词元,内存占用都完全不变。这种恒定的内存占用与注意力机制(section 1.5)形成鲜明对比:全序列注意力在预填充期间会物化一个 \(\mathcal{O}(S^2)\) 的分数矩阵,而自回归生成则维护一个 \(\mathcal{O}(S \cdot d_{\text{model}})\) 的键值缓存。对于部署在微控制器等内存受限边缘硬件上的流式应用,RNN 的 \(\mathcal{O}(1)\) 运行时状态消除了限制 Transformer 的内存容量耗尽问题。

循环执行呈现出独特的内存层次结构行为:参数具有很高的时间局部性,但在标准框架调度下,算术强度较低。权重矩阵 \(\mathbf{W}_{\text{hh}}\) 和 \(\mathbf{W}_{\text{hx}}\) 在每个时间步都会复用;如果模型能够容纳于片上,它们便可轻松驻留在 SRAM 或 L2 缓存中。然而,在每个时间步为输入投影、循环投影、偏置加法和激活分别启动独立内核的朴素做法,会产生严重的内核启动开销,并迫使中间张量在 HBM 之间反复传输。为缓解这一内存带宽瓶颈,生产环境中的循环网络运行时会将投影、偏置加法和激活融合为单个整体内核,在整个序列执行期间将 \(\mathbf{h}_t\) 保留在 GPU 寄存器和共享内存中。

固定容量状态与串行执行之间的这种架构张力,决定了 Transformer 出现之前序列处理的基本形态。尽管循环网络的内存开销始终恒定,不随序列长度变化,但顺序依赖使硬件无法跨时间步并行执行,而固定容量状态也成为信息瓶颈,使早期输入的信息在较长跨度上逐渐消退(即梯度消失问题)。要同时克服这两项约束,就需要一种能够在任意序列位置之间建立直接、可按内容寻址的连接,且无需经过中间循环步骤的架构:注意力机制(section 1.5)。对于已部署的循环处理流水线,算子融合和流水线并行等缓解技术将在 数据流优化 中分析。

注意力:动态处理

循环网络沿序列维度串行执行,并将全部历史上下文压缩为一个固定容量的隐藏状态向量(section 1.4.4)。例如,在“那只猫,正坐在能俯瞰花园的窗边,睡着了”这样的句子中,主语“猫”与谓语“睡着了”在原英文中相隔九个词,但二者构成了核心的句法和语义关系。RNN 必须依次处理其间的所有词元,这既可能在中间的循环状态转换中造成信息丢失,又使硬件无法跨时间步并行执行。这一约束促使人们寻求另一种计算模式:一种能够直接计算任意两个位置之间相关性、而不受距离影响的运算。

注意力机制16通过引入随输入内容变化的动态连接模式,解决了这一局限 (Bahdanau et al. 2015)。编码器—解码器注意力不再强迫所有上下文都经过单个固定容量的状态向量,而是计算每个解码器状态与所有编码器输入位置之间的相似度分数,从而在序列中动态路由信息。

Definition 1.5: 注意力机制

注意力机制是一类神经网络运算,用于计算值向量的加权和,其中权重来自查询向量与一组键向量之间学习得到的相似度分数,从而支持在序列中任意两个位置之间进行依赖内容的动态信息路由。

  1. 意义:注意力以 \(\mathcal{O}(1)\) 的深度连接任意两个词元,但需要计算 \(S^2\) 次分数交互。如果将这些分数物化,那么对于包含 4,096 个词元、采用 16 位分数的序列,每层每个头会消耗 33.6 MB(约 16.8M 个分数,每个 2 字节),直接增大机器学习系统铁律中的 \(D_{\text{vol}}\) 和 \(\text{BW}\) 项。分块精确注意力内核可以避免保留完整矩阵,但稠密分数计算仍然具有二次复杂度。
  2. 区别:RNN 将全部先前上下文压缩到单个固定大小的状态向量中,而注意力机制保留词元表示并直接计算相关性分数。在训练或全序列预填充,即处理整个提示的初始遍历期间,分数交互数量随序列长度呈二次增长;在自回归服务期间,存储的 KV 缓存,即保存的先前词元的键向量和值向量,按 \(\mathcal{O}(S d_{\text{model}})\) 增长,而每个新词元都会对先前的键和值执行注意力运算。
  3. 常见误区:一种常见误解是,注意力是一种可以随意应用的通用加权方案。二次复杂度的分数计算是一项严格的扩展约束:上下文长度翻倍,分数交互数量就会增至四倍。朴素实现的分数存储量也会增至四倍;FlashAttention 等分块精确算法避免了存储完整矩阵,而稀疏变体则减少了需要计算的分数数量。

尽管注意力机制最初被用作循环架构中的组件,但其连接任意两个位置的能力,使许多序列任务不再需要循环结构。Transformer17 架构 (Vaswani et al. 2017) 将注意力与前馈层、残差连接、归一化和位置信息相结合,且不采用循环。这一架构转变将 RNN 的 \(\mathcal{O}(S)\) 顺序路径替换为单个注意力层内各位置之间的恒定路径长度,从而能够在高吞吐量加速器上跨序列位置并行执行。

Transformer 架构(section 1.6)的核心系统属性继承自注意力:依赖内容的路由、并行序列执行,以及分数规模的二次增长。分析这类架构的系统影响,首先需要理解注意力所解决的底层模式处理问题。

模式处理需求

动态模式处理针对的是这样一类场景:元素之间的关系并非由架构固定,而是从内容中涌现。语言翻译就是这一挑战的典型例子:翻译“河边的岸”时,理解原英文中的“bank”需要关注“river”;而在“银行批准了贷款”中,重要关系则是它与“approved”和“loan”的联系。与顺序处理信息的 RNN 或使用固定空间模板的 CNN 不同,动态序列处理需要一种依据词元身份评估关系的运算。figure 6 中的代词消解示意图直观展示了这种动态路由。

\scalebox{0.9}{%
\begin{tikzpicture}[line join=round,font=\small\sffamily]
\tikzset{
  token/.style={rectangle, text width=24mm,minimum width=25mm, minimum height=6mm, draw=none, fill=cyan!50},
  highlight/.style={fill=violet!30},
  attention/.style={draw=cyan, line width=1.5pt, -{Latex[length=6pt]}},
}
% Left
\foreach \i/\clr/\txt in {
  1/cyan!50/这名\_, 2/cyan!50/学生\_, 3/cyan!30/助动词\_, 4/cyan!35/没有\_,
  5/cyan!50/完成\_, 6/cyan!20/全部\_, 7/cyan!20/定冠词\_, 8/cyan!40/作业\_,
  9/cyan!10/因为\_, 10/cyan!30/他们\_, 11/cyan!30/系动词\_, 12/cyan!20/累了\_
} {
  \node[token,fill=\clr,align=right] (T\i l) at (0,-\i*0.62) {\txt};
}
% Right
\foreach \i/\txt in {
  1/这名\_, 2/学生\_, 3/助动词\_, 4/没有\_,
  5/完成\_, 6/全部\_, 7/定冠词\_, 8/作业\_, 9/因为\_,
  10/他们\_, 11/系动词\_, 12/累了\_
} {
  \node[token,fill=white,align=left] (T\i r) at ($(T\i l) + (6.5cm, 0)$) {\txt};
}

% Highlight "they" on the right side
\path (T10l) ++(65mm, 0) node[token, highlight] (T10r) {他们\_};

% Attention with "they"
\draw[attention] (T10r.west) -- (T2l.east); % student
\draw[attention,line width=0.5pt, opacity=0.75] (T10r.west) -- (T1l.east); % The
\draw[attention] (T10r.west) -- (T5l.east); % finish
\draw[attention, opacity=0.75] (T10r.west) -- (T8l.east); % homework
\foreach \i in {3,4,6,7,9,10,11,12}{
\draw[attention,line width=0.25] (T10r.west) -- (T\i l.east);
}
% Title
\node[above=14pt of current bounding box.north,align=center] (TS){这名学生没有完成全部作业,因为他们累了。};
\node[below=-3pt of TS,anchor=north] {\footnotesize 层:4 \quad 头:2};
\end{tikzpicture}}
Figure 6: 注意力模式示例:代词“他们”的注意力模式示意图。线条粗细表示假设的注意力权重大小,与“学生”“完成”和“作业”的连接较强。一个注意力层直接连接所有位置,并能并行计算它们之间的稠密交互。

在 figure 6 中,注意力机制通过为“学生”和“完成”等相关上下文词元分配较大的权重,消解歧义代词“他们”,权重大小由线条粗细表示。由于所有成对连接都被并行评估,网络能够在单层中捕获这种长距离句法依赖,而无需跨越其间的词元传播中间状态。

依赖输入的处理远不限于语言。在蛋白质结构预测中,氨基酸之间的相互作用取决于化学性质和空间排列,而不只是链中的位置。在图分析中,图卷积网络(GCN)在每个节点的观测邻居上聚合特征 (Kipf and Welling 2017)。CNN 按规则的空间步长访问内存,Transformer 则处理稠密序列张量;与它们不同,GCN 的邻居聚合遵循输入图的不规则邻接结构。每次收集操作都会访问一组由具体输入决定的节点嵌入,使缓存预取器失效,并阻碍合并内存访问。因此,不规则的邻居收集模式可能使执行受限于内存带宽和缓存未命中,而非计算吞吐量。在文档分析中,各章节之间的联系取决于语义内容,而非相邻程度。

Kipf, Thomas N, and Max Welling. 2017. “Semi-Supervised Classification with Graph Convolutional Networks.” International Conference on Learning Representations (ICLR).

依赖输入并不意味着全连接。稠密注意力为每一对序列元素计算分数,而 GCN 则将聚合限制在观测图的边上。不同输入对应的图可能需要不同的收集调度,并表现出不同的局部性。共同的系统挑战在于,计算或内存访问模式会响应输入,而非遵循固定模板。即使张量维度保持不变,依赖内容的分数也会决定哪些信息得到强调。注意力提供了一种学习此类关系的机制,而稠密自注意力构成了 Transformer 架构的基础。

算法结构

要满足 section 1.5.1 中的动态路由需求,需要一个将变长序列映射为依赖内容的亲和权重的形式化算子 (Bahdanau et al. 2015)。Transformer 架构通过 Vaswani et al. (2017) 提出的缩放点积注意力算子实现这一映射: \[ \text{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{softmax} \left(\frac{\mathbf{Q}\mathbf{K}^T}{\sqrt{d_k}}\right)\mathbf{V} \]

输入 \(\mathbf{Q}\)(查询)、\(\mathbf{K}\)(键)和 \(\mathbf{V}\)(值)18是词元表示经过学习得到的线性投影。对于长度为 \(S\)、投影维度为 \(d_k\) 的输入序列,点积 \(\mathbf{Q}\mathbf{K}^T\) 计算全部 \(S^2\) 个词元对的相似度(作为相似性度量的点积 将点积形式化为一种相似度度量)。按 \(1/\sqrt{d_k}\) 缩放,可防止点积在高维情况下的幅值过大,否则会将 softmax 推入梯度极小的区域。softmax 算子19将分数矩阵的每一行归一化为键位置上的概率分布。最后,将这些归一化权重与 \(\mathbf{V}\) 相乘,得到由值表示的加权组合构成的输出向量。

Figure 7 展示了长度为 \(S = 6\) 的序列所对应的这一计算流程。所得 \(S{\times}S\) 矩阵的每一行,决定了某个词元对序列中各个词元的关注强度。在训练好的模型中,最大的亲和值反映强烈的上下文依赖,而接近零的元素则抑制无关位置。

\scalebox{0.8}{%
\begin{tikzpicture}[line join=round,font=\sffamily\small]
\tikzset{%
   Line/.style={line width=1.1pt,BrownLine,text=black},
   LineB/.style={line width=1.1pt,cyan!99!red,text=black},
   LineR/.style={line width=1.1pt,red!99!black,text=black,rounded corners=7pt},
   LineBD/.style={line width=2pt,cyan!99!red,text=black,shorten <=126},
   LineBDE/.style={line width=2pt,BrownLine,text=black},
   LineBDD/.style={line width=2pt,GreenD,text=black,shorten <=126},
   LineBDG/.style={line width=2pt,red!99!black,text=black,shorten <=126}
}
  %
  \def\rows{6}
  \def\cols{6}
  \def\r{0.2}
  \def\xgap{0.07}
  \def\ygap{0.07}

\begin{scope}[local bounding box=CEN,shift={($(0,0)+(0,0)$)}]
  %Coordinates of the upper right corner (gradient of the gradient)
  \pgfmathsetmacro\dx{(\cols - 1)*(2*\r + \xgap)}
  \pgfmathsetmacro\dy{(\rows - 1)*(2*\r + \ygap)}
  \pgfmathsetmacro\dmax{max(sqrt(pow(\dx,2) + pow(\dy,2)), 0.0001)}

  \foreach \i [count=\c] in {0,...,\numexpr\rows-1} {
    \foreach \j  in {0,...,\numexpr\cols-1} {
\pgfmathtruncatemacro{\newX}{\j + 1} %
      % Circle position
      \pgfmathsetmacro\x{\j*(2*\r + \xgap)}
      \pgfmathsetmacro\y{-\i*(2*\r + \ygap)}

      % Distance to upper right corner
      \pgfmathsetmacro\ux{\dx - \x}
      \pgfmathsetmacro\uy{-\dy - \y}
      \pgfmathsetmacro\d{sqrt(pow(\ux,2) + pow(\uy,2))}
      \pgfmathsetmacro\norm{0.9 - min(\d/\dmax,1)} % Gradient intensity

      % Interpolation from blue (0,0,1) to light red (1,0.6,0.6)
      \pgfmathsetmacro\R{(1 - \norm)*0.2 + \norm*1.0}
      \pgfmathsetmacro\G{(1 - \norm)*0.42 + \norm*0.2}
      \pgfmathsetmacro\B{(1 - \norm)*1.0 + \norm*0.2}

      \definecolor{cellcol}{rgb}{\R,\G,\B}
      \fill[cellcol] (\x,-\y) circle(\r)coordinate(C\c\newX);
    }
  }
\end{scope}

\begin{scope}[on background layer]
  \foreach \i in{1,2,3,4,5,6}{
\draw[Line](C1\i)--(C6\i);
}

 \foreach \i in{1,3,4,5,6}{
\draw[Line](C\i 1)--(C\i 6);
}
\end{scope}
\begin{scope}[local bounding box=QUE,on background layer,shift={(0,0)}]
\node[below=2mm of CEN]{注意力};
  \foreach \i/\tt in{1/使,2/用户,3/赋能,4/他们,5/可视化,6/数据}{
 \ifnum\i=2
    \path (C\i 1) ++(-5,0) node[left]{\tt};
    \draw[LineBD] (C\i 1)--++(-5,0);
  \else
    \draw[LineB]  (C\i 1)--++(-5,0) node[left]{\tt};
    \draw[LineBD] (C\i 1)coordinate(QW\i)--++(-5,0);
  \fi
}
\end{scope}
\node[above left=0mm and 23mm of QW6,cyan!90!black]{查询};

\coordinate(1D)at($(QW1)+(0,-1.0)$);
\coordinate(2D)at($(1D)+(0,-0.4)$);
\coordinate(3D)at($(1D)+(0,-0.8)$);
\coordinate(4D)at($(1D)+(0,-1.2)$);
\coordinate(5D)at($(1D)+(0,-1.6)$);
\coordinate(6D)at($(1D)+(0,-2.0)$);

 \foreach \i/\tt in{6/使,5/用户,4/赋能,3/他们,2/可视化,1/数据}{
    \path (\i D) ++(-5,0) node[left]{\tt};
    \draw[LineBDD]  (\i D)coordinate(QD\i)--++(-5,0);
}
\node[above left=1mm and 23mm of QD1,GreenD]{值};

\coordinate(1G)at($(QW6)+(0,1.0)$);
\coordinate(2G)at($(1G)+(0,0.4)$);
\coordinate(3G)at($(1G)+(0,0.8)$);
\coordinate(4G)at($(1G)+(0,1.2)$);
\coordinate(5G)at($(1G)+(0,1.6)$);
\coordinate(6G)at($(1G)+(0,2.0)$);
 \foreach \i/\tt in{1/使,2/用户,3/赋能,4/他们,5/可视化,6/数据}{
    \path (\i G) ++(-5,0) node[left]{\tt};
    \draw[LineBDG]  (\i G)coordinate(QG\i)--++(-5,0)coordinate(GO\i);
}
\node[above left=0mm and 23mm of QG6,red!99!black]{键};

\begin{scope}[on background layer,fill opacity=0.5]
 \foreach \i in{1,2,3,4,5,6}{
\draw[LineR](GO\i)-|(C6\i);
}
\end{scope}

\begin{scope}[fill opacity=0.4]
\fill[fill=blue!10](C66)++(0.25,0)to[out=350,in=180]++(355:5.0)coordinate(O1)
--++(270:1.65)coordinate(O2)to[out=185,in=10]($(C16)+(0.25,0)$)--cycle;
\fill[fill=green!20](O1)to[out=225,in=0](QD1)--++(180:4.3)--++(270:2.1)to[out=0,in=220](O2)--cycle;
 \end{scope}

\foreach \i[count=\x] in{0.01,0.2,0.4,0.6,0.8,0.99}{
\draw[LineBDE]($(O1)!\i!(O2)$)--coordinate(X\x)++(0.5,0);
}
\node[above=1mm of X1]{输出};

\end{tikzpicture}}
Figure 7: 查询—键—值注意力机制:对于包含 6 个词元的序列,查询(青色)与键(红色)进行匹配,生成一个包含 \(\mathcal{O}(S^2)\) 个元素的 \(6{\times}6\) 注意力矩阵。网格中单元格的颜色从蓝色渐变为红色,仅用于示意,并非计算得到的权重。每个输出位置依据该矩阵中对应行的权重,聚合所有值(绿色)中的信息。矩阵结构同时揭示了计算模式(36 次相似度计算)和朴素实现的内存瓶颈(存储 \(S^2\) 个注意力权重)。来源:Transformer Explainer (Cho et al. 2025)。

虽然注意力权重随输入词元动态变化,但生成查询、键和值向量需要使用学习得到的参数矩阵进行静态线性投影。在加速器实现中,这三项运算被融合为单次批量矩阵乘法,以最大限度地提高张量核心的饱和度,并消除内核启动开销。Figure 8 展示了这一合并投影过程:将 \(6{\times}768\) 的词元嵌入矩阵与打包的 \(768{\times}2304\) 权重矩阵相乘,即可在一次内核执行中得到拼接的查询、键和值表示。

\begin{tikzpicture}[line join=round,font=\small\sffamily]
\tikzset{
  pics/key/.style = {
    code = {
      % Triangle (arrow)
      \fill[#1] (0,0) -- (1,0.75) -- (0,1.5) -- cycle;

      % Vertical line on the right
      \draw[line width=3pt, #1] (1,0.1) -- (1,1.4);
    }
  },
  pics/key/.default = black % Default color
}

 \begin{scope}[local bounding box=QKV]
 \def\rows{15}
  \def\cols{25}
  \def\lastrows{7}  % number of rows in last column
  \def\size{0.1}

  \foreach \j in {0,...,\cols} {
    % Last column - number of rows
    \pgfmathsetmacro\maxrows{
      (\j == \cols) ? \lastrows : \rows
    }

    \foreach \i in {0,...,\rows} {
      \ifnum\i>\maxrows
        \relax %
      \else
        % Random blend: 30-60
        \pgfmathsetmacro\blend{rnd*60 + 30}
        %
        \ifnum\j<16
          \fill[blue!\blend!white] (\j*\size, -\i*\size) rectangle ++(\size, -\size);
        \else
          \fill[red!\blend!white] (\j*\size, -\i*\size) rectangle ++(\size, -\size);
        \fi
      \fi
    }
  }
 \coordinate (1topLeft) at (0, 0);
\pgfmathsetmacro\ycoord{-\rows*\size - \size}
\pgfmathsetmacro\xcoord{\cols*\size + \size}
\coordinate (1bottomLeft) at (0,{\ycoord});
\coordinate (1topRight) at ({\xcoord},0);
\coordinate (1bottomRight) at (\xcoord,\ycoord);
\end{scope}

\begin{scope}[local bounding box=LEFT,shift={($(0,0)+(-2.5,0)$)}]
  \def\numrects{5}
  \def\w{0.1}
  \def\h{0.4}
  \def\bluefrac{0.6}
  \foreach \i in {0,...,\numexpr\numrects-1} {
    \pgfmathsetmacro\blend{rnd*80 + 10}
    \pgfmathsetmacro\cutoff{\bluefrac * \numrects}
      \fill[black!\blend!white] (\i*\w, 0) rectangle ++(\w, \h);
  }
\coordinate (0bottomLeft) at (0, 0);
\coordinate (0topLeft) at (0,\h);
\coordinate (0topRight) at ({\numrects*\w},{\h});
\coordinate (0bottomRight) at ({\numrects*\w},0);
%%
\def\vi{7pt}
\node[align=right,anchor=east,left= 1pt of $(0bottomLeft)!0.5!(0topLeft)$](0DA){数据};
\node[align=right,below=\vi of 0DA.south east,anchor=east](0VI){可视化};
\node[align=right,below=\vi of 0VI.south east,anchor=east](0EM){赋};
\node[align=right,below=\vi of 0EM.south east,anchor=east](0PO){能};
\node[align=right,below=\vi of 0PO.south east,anchor=east](0US){用户};
\node[align=right,below=\vi of 0US.south east,anchor=east](0TO){以};
\end{scope}

\begin{scope}[local bounding box=BIAS,shift={($(QKV)+(2.75,2.5)$)}]
  \def\numrects{27}
  \def\w{0.3}
  \def\h{0.1}

  \def\bluefrac{0.6}
    \foreach \i in {0,...,\numexpr\numrects-1} {
     % colors (4% do 60%)
    \pgfmathsetmacro\blend{rnd*60 + 4}
\fill[black!\blend!white] (0, -\i*\h) rectangle ++(\w, -\h);
  }
\coordinate (2topLeft) at (0, 0);
\coordinate (2bottomRight) at ({\w}, {-\numrects*\h});
\coordinate (2bottomLeft) at ({0}, {-\numrects*\h});
\coordinate (2topRight) at ({\w}, 0);
\end{scope}

\begin{scope}[local bounding box=RIGHT,shift={($(0,0)+(7.5,0)$)}]
  \def\numrects{17}
  \def\w{0.1}
  \def\h{0.4}
  \def\bluefrac{0.6}
  \foreach \i in {0,...,\numexpr\numrects-1} {
    \pgfmathsetmacro\blend{rnd*90 + 10}
    \pgfmathsetmacro\cutoff{\bluefrac * \numrects}
    \ifnum\i<\cutoff
      \fill[blue!\blend!white] (\i*\w, 0) rectangle ++(\w, \h);
    \else
      \fill[red!\blend!white] (\i*\w, 0) rectangle ++(\w, \h);
    \fi
  }
\coordinate (3bottomLeft) at (0, 0);
\coordinate (3topLeft) at (0,\h);
\coordinate (3topRight) at ({\numrects*\w},{\h});
\coordinate (3bottomRight) at ({\numrects*\w},0);
%%
\def\vi{7pt}
\node[align=right,anchor=east,left= 1pt of $(3bottomLeft)!0.5!(3topLeft)$](DA){数据};
\node[align=right,below=\vi of DA.south east,anchor=east](VI){可视化};
\node[align=right,below=\vi of VI.south east,anchor=east](EM){赋};
\node[align=right,below=\vi of EM.south east,anchor=east](PO){能};
\node[align=right,below=\vi of PO.south east,anchor=east](US){用户};
\node[align=right,below=\vi of US.south east,anchor=east](TO){以};
\end{scope}
%%%%%
\node[align=center,above= 4pt of $(2topLeft)!0.5!(2topRight)$](2BI){偏置};
\node[above=5mm of 3topRight](Q1){QKV};
\path[red](Q1)-|coordinate(T1)($(1topLeft)!0.5!(1topRight)$);;
\node[]at(T1){QKV 权重};
\path[red](Q1)-|coordinate(T0)(0topRight);
\node[]at(T0){嵌入};
%%
\node[below=25mm of 3bottomRight](Q2){矩阵(6,2304)};
\path[red](Q2)-|coordinate(TT1)($(1bottomLeft)!0.5!(1bottomRight)$);
\node[]at(TT1){矩阵(768,2304)};
\path[red](Q2)-|coordinate(TT2)(0bottomRight);
\node[]at(TT2){矩阵(6,768)};
\path[red](Q2)-|coordinate(TT3)(2bottomRight);
\node[]at(TT3){向量(2304)};

\node[left= 20pt of $(1bottomLeft)!0.5!(1topLeft)$](PLUS){\LARGE $\times$};
\node[right= 20pt of $(1bottomRight)!0.5!(1topRight)$](PLUS){\LARGE +};
\node[right= 20pt of PLUS](JED){\LARGE=};
%%
\scoped[on background layer]
\node[outer sep=0pt,draw=BackLine,inner xsep=3mm,inner ysep=23,yshift=-7mm,
           fill=BackColor!20,fit=(0VI)(2BI)(Q2),line width=1pt](BB1){};
\node[above=5pt of  BB1.south,anchor=south]{$\displaystyle\sum\limits_{d=1}^{768}E_{id}\cdot W_{dj}+b_j=QKV_{ij}$};
%
\draw[outer sep=0pt,line width=1pt,draw=BackLine,fill=BackColor!45](BB1.north west)rectangle($(BB1.north east)+(0,1)$);
\coordinate (B) at ($(BB1.north west)+(0,1)$);
\coordinate (C) at ($(BB1.north east)+(0,1)$);
\node[right=5pt of $(BB1.north west)!0.5!(B)$]{\textbf{QKV 计算}};

 \pic[shift={(-1,0)},scale=0.4,rotate=0] at ($(BB1.north east)!0.2!(C)$) {key=OliveLine!90!black};
\end{tikzpicture}
Figure 8: QKV 投影计算:嵌入矩阵(\(6{\times}768\))与 QKV 权重矩阵(\(768{\times}2304\))相乘,再加上偏置,得到合并投影(\(6{\times}2304\))。2304 维输出包含拼接后的查询、键和值投影(各为 768 维)。这一次批量矩阵乘法需要 \(6{\times}768{\times}2304\) = 10.6 million MACs,取代了 3 次独立的投影操作,以提高效率。来源:Transformer Explainer (Cho et al. 2025)。
Cho, Aeree, Grace C. Kim, Alexander Karpekov, Alec Helbling, Zijie J. Wang, Seongmin Lee, Benjamin Hoover, and Duen Horng (Polo) Chau. 2025. “TRANSFORMER EXPLAINER: Interactive Learning of Text-Generative Models.” Proceedings of the AAAI Conference on Artificial Intelligence 39 (28): 29625–27. https://doi.org/10.1609/aaai.v39i28.35347.

计算映射

将注意力算子 \(\text{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{softmax}(\mathbf{Q}\mathbf{K}^T/\sqrt{d_k})\mathbf{V}\) 降低到物理执行层面,会显现出数据依赖连接的系统成本。计算成对匹配关系时,每个注意力头需要执行两次不同的矩阵乘法:分数 GEMM(\(\mathbf{Q}\mathbf{K}^T\))和上下文 GEMM(\(\mathbf{A}\mathbf{V}\),其中 \(\mathbf{A} = \text{softmax}(\mathbf{S})\))。对于序列长度为 \(S\)、头维度为 \(d_k\) 的输入,每个阶段执行 \(S^2 d_k\) 次乘加运算,因此每个头的计算复杂度为 \(\mathcal{O}(S^2 d_k)\)。

Listing 7 将高层矩阵表述与显式循环实现进行了对比,后者揭示了这种二次增长规律。矩阵版本被降低为在加速器张量核心上运行的优化 GEMM 例程,而循环版本则揭示了底层的物理执行结构:批次迭代、数量呈二次增长的查询与键内积、逐行 softmax 归约,以及最后遍历所有序列位置的值累加过程。

Listing 7: 注意力计算:两种实现具有相同的 \(\mathcal{O}(S^2\times d)\) 复杂度。矩阵形式(上)使用优化的 GEMM,而嵌套循环(下)则揭示了数量呈二次增长的成对比较:对于长度为 512、维度为 64 的序列,每个注意力头计算注意力分数需要 \(512{\times}512{\times}64\) = 16.8M MACs,值聚合还需要额外的 16.8M MACs。
def attention_layer_matrix(Q, K, V):
    # Q, K, V: (batch_size × seq_len × d_model)
    # Compute attention scores
    scores = matmul(Q, K.transpose(-2, -1)) / sqrt(d_k)
    weights = softmax(scores)  # Normalize scores
    output = matmul(weights, V)  # Combine values
    return output


def attention_layer_compute(Q, K, V):
    # Initialize outputs
    scores = np.zeros((batch_size, seq_len, seq_len))
    outputs = np.zeros_like(V)

    # Loop 1: Process each sequence in batch
    for b in range(batch_size):
        # Loop 2: Compute attention for each query position
        for i in range(seq_len):
            # Loop 3: Compare with each key position
            for j in range(seq_len):
                # Compute attention score
                for d in range(d_model):
                    scores[b, i, j] += Q[b, i, d] * K[b, j, d]
                scores[b, i, j] /= sqrt(d_k)

        # Apply softmax to scores
        for i in range(seq_len):
            scores[b, i] = softmax(scores[b, i])

        # Loop 4: Combine values using attention weights
        for i in range(seq_len):
            for j in range(seq_len):
                for d in range(d_model):
                    outputs[b, i, d] += scores[b, i, j] * V[b, j, d]

    return outputs

对系统的影响

由于需要动态连接,注意力机制呈现出与先前架构不同的独特系统级模式。从机器学习系统铁律(机器学习系统铁律)的角度看,注意力将瓶颈从 RNN 中受延迟限制的顺序执行路径,转移到了数量呈二次增长的分数交互以及依赖于实现方式的数据移动。朴素实现会显式存储一个 \(\mathcal{O}(S^2)\) 的注意力矩阵,而 FlashAttention 等分块算法通过重新计算并使数据块流经更快的存储器,避免存储完整矩阵(在线 softmax 递推的逐步过程以及 I/O 减少量的推导见 FlashAttention 分块与在线 Softmax 递推证明)。

存储需求

注意力机制需要存储查询、键、值投影以及中间特征表示。朴素实现还会为每个序列的每个头显式存储一个 \(S{\times}S\) 的注意力权重矩阵,在 \(S{\times}d\) 的输入和输出之外形成一个二次增长的存储瓶颈。对于长序列,尽管学习得到的投影矩阵大小保持不变,这些临时分数仍可能占据加速器内存的主要部分。FlashAttention 等分块精确注意力内核使分数块流经更快的存储器,避免在 HBM 中保留完整矩阵,但仍然需要计算 \(S^2\) 次稠密交互。这一区别将稠密注意力不可避免的二次计算成本与可避免的二次分数存储需求区分开来。如果内核不采用分块处理,在生产环境的序列长度下,显式存储中间分数矩阵会迅速耗尽加速器的高带宽内存。

一条起初平缓、随后如曲棍球杆般急剧上扬的曲线;圆点标出了拐点,拐点右侧区域以红色阴影标为危险区。

上下文长度加倍,分数交互次数和朴素实现的分数存储量均增至四倍。

Napkin Math 1.1: 二次增长瓶颈
问题:当序列长度 \(S =\) 100,000(上下文窗口)时,显式存储的注意力矩阵需要占用多少内存?

数学计算:

  1. 矩阵大小:每个头的注意力分数矩阵 \((\mathbf{Q}\mathbf{K}^T)\) 的维度为 \(S{\times}S\),共有 \(N_{\text{heads}}\) 个头(本例中为 12 个头)。
  2. 元素数量:100,000 \(\times\) 100,000 \(\times\) 12 个头 = 1.2 × 10¹¹ 个元素。
  3. 内存占用:采用 FP16(每个元素 2 字节):1.2 × 10¹¹ \(\times\) 2 字节 = 240 GB。
  4. 保留的层:每层 240 GB \(\times\) 32 个保留层 = 7,680 GB。

系统洞察:显式存储的注意力矩阵每层占用 240 GB。如果朴素训练实现为了反向传播而保留全部 32 层的分数,则需要 7,680 GB,远超任何单个 GPU 的容量。这一内存墙促成了后文将介绍的两大类实现策略:通过对计算进行分块来避免显式存储完整矩阵,或从一开始就减少需要计算的分数数量。

计算与数据移动

注意力计算分为两个主要的 GEMM 阶段,两者之间穿插逐行归约:生成成对的查询与键分数,以及计算值的加权和。查询与键的内积需要 \(B \times H \times S^2 \times d_k\) 次 MAC 运算,值聚合阶段所需的运算量与之对称相同。两者之间的 softmax 需要逐行求最大值、求指数和求和。静态权重卷积在固定网格位置之间复用滤波器权重,而注意力计算的是依赖于输入的临时亲和度矩阵,每当词元配置发生变化时,都必须重新计算。

Checkpoint 1.3: 对二次增长的直观理解

注意力的成本影响着长上下文的扩展。检验你的直观理解:

注意力中的数据移动会产生不同于固定模板运算的内存访问模式。计算注意力需要对查询、键和值张量进行投影并以流式方式传输,随后根据动态计算的分数对值向量进行路由。在朴素实现中,将中间的 \(S \times S\) 分数矩阵暂存于全局 HBM/DRAM,会使分数的显式存储成为主要的带宽瓶颈。静态卷积受益于确定性的缓存行访问,RNN 则跨时间步复用权重,而朴素注意力会产生大量短暂存在的激活数据,给常规片上缓存容量带来挑战。

Example 1.5: 二次增长墙
场景:早期 BERT 部署在推理和预填充阶段,严格将上下文序列长度限制为 512 个词元 (Devlin et al. 2019)。

诊断:标准自注意力会显式存储一个 \(S \times S\) 的分数矩阵,其内存占用呈二次增长(\(\mathcal{O}(S^2)\))。将序列长度从 512 增加到 4,096,会使分数的内存占用增至原来的 64×,引发 GPU 内存不足崩溃。

系统经验:超线性的内存增长会将算法复杂度转化为硬件瓶颈。为长序列提供服务,需要采用 FlashAttention I/O 分块、稀疏注意力或严格的词元截断,以限制 SRAM 中激活数据的占用。

注意力以动态、恒定深度的路由取代了循环模型中串行化隐状态的瓶颈,但也将系统负担转移到了呈二次增长的算术运算量和大量的内存带宽流量上。与前馈层、残差连接和归一化结合后,这一基本算子能够在现代加速器上实现端到端的并行序列处理。Transformer 架构(section 1.6)直接建立在这一基础之上,确立了现代大规模机器学习系统的主导架构范式。

Transformer:并行序列处理

注意力提供了一种计算原语,用于在位置之间实现动态的、依赖内容的路由,但它最初叠加在循环架构之上,因而继承了其顺序执行瓶颈。Transformer 架构 将注意力与前馈层、残差连接、归一化和位置信息相结合,消除了循环机制。这使得模型能够在完整序列处理期间跨序列位置并行计算,同时保留动态连接能力。这一架构转变引入了不同的物理成本:预填充期间的二次复杂度稠密分数计算、服务期间不断累积的键值状态,以及自回归生成期间巨大的内存带宽压力。

Definition 1.6: Transformer

Transformer 是一种神经网络架构,它将自注意力、前馈层、残差连接、归一化和位置信息相结合,不使用循环机制,从而能够在训练和预填充期间跨序列位置并行处理。

  1. 意义:并行性是其在系统层面的收益。RNN 处理一个包含 \(S\) 个词元的序列时,需要执行 \(S\) 个具有顺序依赖关系的步骤。Transformer 并发处理序列中的所有位置,将词元之间的交互映射为大型矩阵乘法(GEMM),以最大限度地提高加速器的计算利用率。稠密自注意力计算 \(\mathcal{O}(S^2)\) 次成对分数交互,而朴素实现会在高带宽内存(HBM)中显式存储一个 \(\mathcal{O}(S^2)\) 的中间激活张量。
  2. 区别:在循环骨干网络内部使用的注意力会继承宿主架构的 \(\mathcal{O}(S)\) 顺序执行路径,而 Transformer 将注意力用作位置之间的主要混合运算,并与逐位置前馈网络交替执行。
  3. 常见误区:一种常见误解是 Transformer 具有“无限上下文”。上下文长度受到两种不同内存占用的限制:训练和预填充期间的 \(\mathcal{O}(S^2)\) 注意力分数激活矩阵,以及自回归服务期间不断累积的 \(\mathcal{O}(S)\) 键值(KV)缓存。当序列较长时,KV 缓存的占用可能与静态模型权重相当,甚至超过后者,使 KV 缓存管理和内存带宽效率成为主要的工程约束。

模式处理需求

注意力机制最初作为循环序列到序列架构的附加组件出现 (Sutskever et al. 2014; Bahdanau et al. 2015)。这些混合模型改善了长上下文中的动态连接能力,但保留了循环状态更新过程:第 \(t\) 步仍然严格依赖第 \(t-1\) 步,无法在并行硬件上跨序列位置并发执行。消除循环机制需要用序列中的全对全交互替代顺序状态传播,以每步有界的内存占用为代价,换取加速器上的并行执行。

Sutskever, Ilya, Oriol Vinyals, and Quoc V. Le. 2014. “Sequence to Sequence Learning with Neural Networks.” Advances in Neural Information Processing Systems (NeurIPS) 27: 3104–12.

Transformer 架构 (Vaswani et al. 2017) 将自注意力确立为跨位置的主要混合原语,并配合位置编码注入序列顺序。这一架构选择牺牲了 CNN 的空间参数效率和 RNN 有界的 \(\mathcal{O}(1)\) 单步状态,换取训练和预填充期间不受循环依赖约束的序列并行性。

算法结构

Transformer 的架构转变以自注意力层为核心。在编码器—解码器注意力中,查询来自目标序列,键和值来自源序列;与之不同,自注意力 从同一个输入序列 \(\mathbf{X}\) 中生成查询、键和值。让这三种投影均指向序列自身,使模型能够在不经过中间循环步骤的情况下,解析任意词元距离上的序列内部依赖关系。Equation 7 形式化地描述了这一变换: \[ \text{SelfAttention}(\mathbf{X}) = \text{softmax} \left(\frac{\mathbf{X}\mathbf{W}_Q(\mathbf{X}\mathbf{W}_K)^T}{\sqrt{d_k}}\right)\mathbf{X}\mathbf{W}_V \tag{7}\]

其中,\(\mathbf{X}\) 是输入序列,\(\mathbf{W}_Q\)、\(\mathbf{W}_K\) 和 \(\mathbf{W}_V\) 分别是查询、键和值的可学习权重矩阵。该表达式突出了自注意力如何从同一输入中生成全部组成部分,形成动态的、依赖内容的处理模式。由于矩阵乘法和逐行 softmax 在词元维度上以对称方式运算,自注意力具有严格的置换等变性:打乱 \(\mathbf{X}\) 的行,只会使输出行发生相同的重排,相当于将序列视为无序集合。因此,需要将位置编码注入表示中,无论是添加正弦向量,还是应用旋转位置嵌入,都是为了打破这种对称性,编码词序和相对距离。

Transformer 通过多头注意力 并行执行多个注意力运算,扩展了单头自注意力。该架构并非在 \(d_{\text{model}}\) 维度上计算一组注意力权重,而是将查询、键和值投影到 \(N_{\text{heads}}\) 个不同的低维子空间中,每个子空间的维度为 \(d_k = d_{\text{model}} / N_{\text{heads}}\)。各个注意力头 同时关注不同的表示模式。它们的输出经拼接后,再通过输出矩阵 \(\mathbf{W}^O\) 进行投影,如 equation 8 所示: \[ \text{MultiHead}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{Concat}(\text{head}_1, \ldots, \text{head}_{N_{\text{heads}}})\mathbf{W}^O \tag{8}\] 其中,每个注意力头的计算方式为: \[ \text{head}_i = \text{Attention}(\mathbf{Q}\mathbf{W}_i^Q, \mathbf{K}\mathbf{W}_i^K, \mathbf{V}\mathbf{W}_i^V) \]

缩放因子 \(\sqrt{d_k}\) 用于保证数值和梯度的稳定性。假设查询和键的各分量是均值为零、方差为一的独立随机变量,则其内积 \(\mathbf{q}_i \cdot \mathbf{k}_j = \sum_{m=1}^{d_k} q_{im} k_{jm}\) 的均值为零、方差为 \(d_k\)。如果不进行缩放,较大的注意力头维度会使点积进入 softmax 函数饱和、梯度接近零的区域。除以 \(\sqrt{d_k}\) 可将方差归一化为一,保持梯度稳定,从而实现有效学习。20

从概念上讲,注意力实现了一种可微的内容寻址存储器。传统存储器架构通过显式地址检索所存储的值,而自注意力使用查询向量 \(\mathbf{q}_i\),对所有候选键 \(\mathbf{K} \in \mathbb{R}^{S \times d_k}\) 计算相似度分数。所得的 softmax 分布对值向量 \(\mathbf{V} \in \mathbb{R}^{S \times d_v}\) 进行连续插值,发挥可微查找运算的作用。

从信息论角度看,注意力机制实现了平滑的信息聚合。softmax 权重在键的位置上形成一个类别分布,其分布熵量化了路由是高度集中还是较为分散 (Cover and Thomas 2006)。这在两个相互竞争的目标之间取得平衡:将概率质量集中于相关词元,同时保留足够的熵,避免脆弱的硬选择决策。

Cover, Thomas M., and Joy A. Thomas. 2006. Elements of Information Theory. 2nd ed. Wiley. https://doi.org/10.1002/047174882X.

然而,满秩多头注意力经常表现出结构冗余,多个头会学习到相互关联的注意力图。此外,softmax 中的指数运算使其在低精度格式下对下溢和上溢极为敏感。这些与硬件相关的行为推动了结构化剪枝、低秩分解、稀疏注意力模式和专用量化策略的发展,详见 模型压缩。

自注意力学习输入序列中的动态激活模式。CNN 应用固定的滤波器,RNN 使用固定的循环模式,而注意力根据元素的内容学习哪些元素应共同激活。训练后的注意力头往往专门捕获不同的句法或语义模式 (Clark et al. 2019),为每个输入序列动态调整其有效连接图。

Clark, Kevin, Urvashi Khandelwal, Omer Levy, and Christopher D. Manning. 2019. “What Does BERT Look at? An Analysis of BERT’s Attention.” Proceedings of the 2019 ACL Workshop BlackboxNLP: Analyzing and Interpreting Neural Networks for NLP, 276–86. https://doi.org/10.18653/v1/w19-4828.

Transformer 架构将这种自注意力机制应用于一个更大的结构中,该结构通常还包括前馈层、层归一化 和残差连接。Figure 9 展示了输入词元进入重复堆叠的注意力块和前馈块,每个块都由残差连接和归一化包围,最终输出上下文化表示。由于所有位置都可以并行处理,无须顺序执行,该架构以大型矩阵运算替代循环状态,而这些运算非常适合加速器训练。

\scalebox{0.8}{%
\begin{tikzpicture}[font=\small\sffamily]
\tikzset{%
  do path picture/.style={%
    path picture={%
      \pgfpointdiff{\pgfpointanchor{path picture bounding box}{south west}}%
        {\pgfpointanchor{path picture bounding box}{north east}}%
      \pgfgetlastxy\x\y%
      \tikzset{x=\x/2,y=\y/2}%
      #1
    }
  },
  sin wave/.style={do path picture={
    \draw [line cap=round,line width=1.5pt] (-3/4,0)
      sin (-3/8,1/2) cos (0,0) sin (3/8,-1/2) cos (3/4,0);
  }},
  cross/.style={do path picture={
    \draw [line cap=round,line width=1.75pt] (-1,-1) -- (1,1) (-1,1) -- (1,-1);
  }},
  plus/.style={do path picture={
    \draw [line cap=round,line width=1.5pt] (-3/4,0) -- (3/4,0) (0,-3/4) -- (0,3/4);
  }}
}

\tikzset{%
  Box/.style={align=flush center,
    inner xsep=2pt,
    node distance=0.9,
    draw=RedLine,%GreenLine,
    line width=0.75pt,
    fill=magenta!05,
    minimum width=32mm, minimum height=10mm},
  Box2/.style={Box, draw=GreenD, fill=GreenL!25},
  Box3/.style={Box, draw=mybrown, fill=mybrown!06, minimum height=5.5mm, node distance=0.25},
  Box4/.style={Box, draw=myblue, fill=cyan!05},
  Box5/.style={Box, draw=myorange, fill=myorange!06, minimum height=6mm},
  Circ/.style={draw,circle,inner sep=1pt,thick,minimum size=7mm, fill=mygreen!10,
  font=\huge\sffamily\bfseries},
  Circ2/.style={draw=black ,circle,minimum size=10mm, fill=mygreen!10,thick},
  Txt/.style={align=center,font=\sffamily\footnotesize,text=black},
  Txt2/.style={font=\sffamily\fontsize{9pt}{9}\selectfont,text=black!60,align=left,},
  ALine/.style={draw=black!40,line width=0.6pt,{{Triangle[width=1.0*4pt,length=7pt]}-},shorten <=0pt,shorten >=0pt},
  LineA/.style={draw=black!40,line width=0.6pt,{-{Triangle[width=1.0*4pt,length=7pt]}},shorten <=0pt,shorten >=0pt},
  Line/.style={draw=black!40,line width=0.6pt,shorten <=0pt,shorten >=0pt},
}

%};%
\node[Box](LB1){输入\\ 嵌入};
\node[above=0.55 of LB1,Circ, plus](LC1){};
\node[left=of LC1,Circ2,sin wave](LC2){};
\node[Box2,above=1.4 of LC1](LB2){多头\\ 注意力};
\node[Box3,above=of LB2](LB3){相加 \& 归一化};
\node[Box4,above=of LB3](LB4){前馈 \\ 网络};
\node[Box3,above=of LB4](LB5){相加 \& 归一化};
%
\node[left=1pt of LC2,Txt]{位置\\ 编码};
%arrows
\draw[ALine](LB1.south)--++(0,-7mm)node[below=-3pt]{输入};
\draw[LineA](LB1)--(LC1);
\draw[LineA](LC1)--coordinate[pos=0.4](LSR1)(LB2);
\draw[LineA](LC1)--++(0,11mm)-|(LB2.330);
\draw[LineA](LC1)--++(0,11mm)-|(LB2.210);
%
\draw[Line](LB2)--(LB3);
\draw[LineA](LB3)--coordinate[pos=0.4](LSR2)(LB4);
\draw[Line](LB4)--(LB5);
%
\draw[LineA](LSR1)--++(-25mm,0)coordinate(LC01)|-(LB3);
\draw[LineA](LSR2)--++(-25mm,0)coordinate(LC02)|-(LB5);
%
\draw[Line](LC1)--(LC2);
%%
\begin{scope}[on background layer]
\node[draw=BackLine,fill=BackColor!06,inner xsep=3mm,fit=(LC01)(LC02)(LB5)](BB1){};
\node[left=1pt of BB1.west]{$N_L\times$};
\end{scope}
%%%%%%%%%%%%%%
%right
%%%%%%%%%%%%%%
\node[Box,right=3.1 of LB1](RB1){输出\\ 嵌入};
\node[above=0.55 of RB1,Circ, plus](RC1){};
\node[right=of RC1,Circ2,sin wave](RC2){};
\node[Box2,above=1.4 of RC1](RB2){掩码多头\\ 注意力};
\node[Box3,above=of RB2](RB3){相加 \& 归一化};
\node[Box2,above=of RB3](RB4){多头\\ 注意力};
\node[Box3,above=of RB4](RB5){相加 \& 归一化};
%
\node[Box4,above=of RB5](RB6){前馈 \\ 网络};
\node[Box3,above=of RB6](RB7){相加 \& 归一化};
%
\node[Box5,above=0.5 of RB7](RB8){线性层};
\node[Box5,above=0.5 of RB8](RB9){Softmax};
%
\node[right=1pt of RC2,Txt]{位置\\ 编码};
%arrows
\draw[ALine](RB1.south)--++(0,-7mm)node[below=-3pt]{输出(右移)};
\draw[LineA](RB1)--(RC1);
\draw[LineA](RC1)--coordinate[pos=0.4](RSR1)(RB2);
\draw[LineA](RC1)--++(0,11mm)-|(RB2.330);
\draw[LineA](RC1)--++(0,11mm)-|(RB2.210);
%
\draw[Line](RB2)--(RB3);
\draw[LineA](RB3)--coordinate[pos=0.32](RSR2)(RB4);
\draw[Line](RB4)--(RB5);
%%
\draw[LineA](RB5)--coordinate[pos=0.4](RSR3)(RB6);
%
\draw[LineA](RSR1)--++(25mm,0)coordinate(RCO1)|-(RB3);
\draw[LineA](RSR2)--++(25mm,0)coordinate(RCO2)|-(RB5);
\draw[LineA](RSR3)--++(25mm,0)coordinate(RCO2)|-(RB7);

\draw[Line](RB6)--(RB7);
\draw[Line](RC1)--(RC2);
%
\draw[LineA](RB7)--(RB8);
\draw[LineA](RB8)--(RB9);
%
\begin{scope}[on background layer]
\node[draw=BackLine,fill=BackColor!06,inner xsep=3mm,fit=(RCO1)(RCO2)(RB7)](BB2){};
\node[right=1pt of BB2.east]{$N_L\times$};
\end{scope}
%%
\draw[LineA,line width=0.85pt,black](LB5)--++(0,15mm)--++(28.5mm,0)--++(0,-37mm)coordinate(PT1)
-|(RB4.330);
\draw[LineA,line width=0.85pt,black](PT1)-|(RB4.210);
\draw[LineA,line width=0.85pt,black](PT1)-|(RB4.270);
%
\draw[LineA](RB9.north)--++(0,5mm)node[above=-3pt]{输出概率};
\end{tikzpicture}}
Figure 9: Transformer 架构(编码器—解码器):完整架构。编码器(左侧,重复 \(N_L\) 次)由多头注意力和随后的前馈层组成,两者均配有残差连接(绕过模块的箭头)和层归一化。解码器(右侧)增加了掩码注意力,以防止自回归生成期间关注未来词元。位置编码(正弦波)注入了置换不变的注意力运算所缺少的序列顺序信息。这一设计支持训练期间所有位置的并行处理,同时使解码器在推理期间保持自回归因果性。来源:(Vaswani et al. 2017)。

计算映射

增大序列长度 \(S\) 会对加速器的内存层次结构构成挑战,因为完整序列自注意力的开销随上下文长度呈二次增长。Figure 10 展示了这一发展轨迹:早期 Transformer 模型的上下文窗口为 512 至 2,048 个词元 (Devlin et al. 2019; Radford et al. 2019; Brown et al. 2020),而现代生产模型支持的上下文窗口从 128,000 个词元到超过一百万个词元不等 (OpenAI 2023; Anthropic 2023; Google 2024)。应将这些产品名称视为历史上的规模参照:长期有效的系统原则是,更长的上下文窗口会将复杂性从外部检索和文档分块流水线转移到加速器本身的内存容量和带宽预算上。FlashAttention (Dao et al. 2022) 等算法分块技术和稀疏近似减少了中间内存分配,但并未消除注意力状态的根本扩展规律。

Radford, Alec, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei, and Ilya Sutskever. 2019. Language Models Are Unsupervised Multitask Learners. OpenAI.
OpenAI. 2023. New Models and Developer Products Announced at DevDay.
Anthropic. 2023. Introducing Claude 2.1.
Google. 2024. Our Next-Generation Model: Gemini 1.5.

Figure 10: 上下文窗口的爆炸式增长:从早期模型(512 至 2K 个词元)到现代长上下文架构(128K 至 1M 个词元)的模型上下文容量(词元数,对数刻度)。当上下文规模扩大 \(1,000\times\) 时,朴素注意力的内存占用增长 \(1,000,000\times\)(\(\mathcal{O}(S^2)\)),推动了 FlashAttention、稀疏注意力和线性注意力机制的发展。

Listing 8 给出了一个典型实现,展示自注意力如何从同一输入序列中生成查询、键和值。

Listing 8: 自注意力与多头注意力:自注意力(上)通过三个投影,从同一输入 \(\mathbf{X}\) 中生成 \(\mathbf{Q}\)、\(\mathbf{K}\) 和 \(\mathbf{V}\),随后按前述方式计算注意力。多头注意力(下)并行运行 \(N_{\text{heads}}\) 个注意力头,每个头的维度为 \(d_k = d_{\text{model}}/N_{\text{heads}}\),然后进行拼接和投影。对于 GPT-2(768 维,12 个头),每个头在 64 维上运算,将投影后的特征维度划分给各个头,同时支持多样的关系模式。
def self_attention_layer(X, W_Q, W_K, W_V, d_k):
    # X: input tensor (batch_size × seq_len × d_model)
    # W_Q, W_K, W_V: weight matrices (d_model × d_k)

    Q = matmul(X, W_Q)
    K = matmul(X, W_V)
    V = matmul(X, W_V)

    scores = matmul(Q, K.transpose(-2, -1)) / sqrt(d_k)
    attention_weights = softmax(scores, dim=-1)
    output = matmul(attention_weights, V)

    return output

def multi_head_attention(X, W_Q, W_K, W_V, W_O, num_heads, d_k):
    outputs = []
    for i in range(num_heads):
        head_output = self_attention_layer(
            X, W_Q[i], W_K[i], W_V[i], d_k
        )
        outputs.append(head_output)

    concat_output = torch.cat(outputs, dim=-1)
    final_output = matmul(concat_output, W_O)

    return final_output

并行序列处理在自回归推理期间发生根本变化:逐步生成输出词元重新引入了顺序串行执行,并将受计算限制的矩阵乘法转变为受内存带宽限制的矩阵—向量运算,section 1.6.4 通过 GPT-2 XL 这一标杆案例对此进行了量化。

系统影响

section 1.5.4 中分析的二次复杂度瓶颈,在不同执行模式下有不同表现。完整序列训练和预填充并发计算所有词元位置,而自回归解码每次生成一个词元。因此,运算瓶颈从受计算限制的矩阵乘法转移到受内存带宽限制的权重和状态读取,并受到序列长度、批大小和内存层次结构限制的共同制约。

训练:二次复杂度计算壁垒

在训练和提示词预填充期间,所有词元位置均并行处理,使加速器的张量核心能够实现较高的浮点计算利用率。然而,稠密注意力的分数计算量随序列长度 \(S\) 按 \(\mathcal{O}(S^2)\) 增长。对于长序列(例如 32k 个词元),显式构建 \(32k{\times}32k\) 的注意力矩阵时,每层多个注意力头合计需要数 GB 的激活存储空间。将这一二次规模的中间矩阵写入加速器 HBM,再将其读回以计算 softmax,会造成极为严重的内存带宽瓶颈。这一物理约束推动了 I/O 感知的内核分块技术(例如 FlashAttention (Dao et al. 2022))的发展:该技术将点积、softmax 和值加权步骤融合到高速片上 SRAM 分块中执行,避免了中间 \(\mathcal{O}(S^2)\) 矩阵在 HBM 中的往返传输。使此类分块技术有效的硬件存储层次结构(HBM、SRAM、寄存器文件)详见 硬件加速。

小批量自回归解码:内存带宽墙

自回归解码每次生成一个词元,在批量大小为 1 或较小时,通常受内存带宽限制。为生成一个词元,系统大体执行以下三项操作:

  1. 读取模型权重,其复用程度取决于批处理和存储层次结构(例如,一个具有 700 亿参数的模型需存储 140 GB 的 FP16 权重;GPT-2 XL 可以具体说明这一步的开销)。
  2. 执行矩阵—向量乘法。
  3. 读写 KV 缓存。

KV 缓存21 随序列长度线性增长(每个请求为 \(\mathcal{O}(N_L \times 2 \times N_{\text{heads}} \times S \times d_{\text{head}})\),不同于训练期间的 \(\mathcal{O}(S^2)\) 注意力分数矩阵),它存储所有先前词元的键向量和值向量,以避免重复计算 (Pope et al. 2023; Kwon et al. 2023)。保留过去词元的键和值,是因为新生成词元的查询(\(q_{t}\))必须对全部历史上下文(\(k_1 \dots k_{t-1}\) 和 \(v_1 \dots v_{t-1}\))计算注意力,才能得到其下一个表示。先前的查询(\(q_1 \dots q_{t-1}\))可以安全丢弃,因为过去的词元永远不会向前关注未来的词元;而缓存过去的键和值,则避免了每生成一个词元时都针对完整提示词重新执行整个模型的前向传播。对于长上下文,这一缓存可能变得极为庞大(例如超过 100 GB),且每个解码步骤都要读取先前的键和值。由此产生的带宽压力取决于上下文长度、批处理、注意力架构、缓存布局和硬件。

Lighthouse 1.5: GPT-2 XL(带宽标杆案例)

重要性:GPT-2 XL 是批量大小为 1 时解码受内存带宽限制 的典型示例。在此处仅考虑权重的模型中,每个解码步骤读取 6 GB 的 FP32 权重,并执行矩阵—向量运算。由此得到的算术强度在采用 FP32 权重时约为 0.5 FLOP/byte,采用 FP16 权重时约为 1 FLOP/byte。批处理可以摊薄这部分权重传输量,而 KV 缓存和激活的传输则会增加总传输量。Table 6 汇总了这一带宽标杆案例的定量特征:

Table 6: GPT-2 XL 的系统特征:针对批量大小为 1 的自回归解码,仅考虑权重所得的估算。在这些假设下,每一步都读取模型权重,算术强度约为 0.5–1 FLOP/byte,因此 HBM 带宽对生成吞吐量构成强约束。
属性 值 系统影响
参数量 1.5B 权重加载主导推理延迟。
模型大小 6 GB (FP32) 可装入单个 GPU,但会耗尽 HBM 带宽。
计算量 3 GFLOP/token 每个词元的计算量较低;瓶颈在于数据搬移,而非数学运算。
约束 内存带宽 受权重传输限制的单批量解码,其每秒词元数高度依赖 HBM 带宽。
特征 带宽受限(小批量解码) 更大的批量可以摊薄权重传输量,并使瓶颈转移。

在训练和推理中,Transformer 呈现出不同的运行特征:训练期间各词元位置之间不受约束的并行执行、随上下文长度呈二次增长的算术复杂度,以及自回归解码期间受带宽限制的权重流式读取。

然而,稠密模型和空间模型并未涵盖生产工作负载的全部类型。大规模推荐系统将稀疏嵌入查找与下游稠密交互层结合起来,因而不同于标准的算术运算主导型流水线;在稀疏嵌入查找中,内存容量和不规则访问分布决定了吞吐量。这种混合模式在生产规模下具有重要意义:Meta 报告称,推荐模型占据了其 AI 推理周期的大部分 (Gupta et al. 2020),尽管这类工作负载受到的学术关注少于语言模型或视觉模型。Section 1.7 将推荐系统作为本章的最后一种范式进行讨论。

Gupta, Udit, Carole-Jean Wu, Xiaodong Wang, Maxim Naumov, Brandon Reagen, David Brooks, Bradford Cottel, et al. 2020. “The Architectural Implications of Facebook’s DNN-Based Personalized Recommendation.” 2020 IEEE International Symposium on High Performance Computer Architecture (HPCA), 488–501. https://doi.org/10.1109/HPCA47549.2020.00047.

稀疏架构:推荐系统

当用户打开流媒体服务或电子商务平台时,系统必须在 50 ms 以内从包含数百万个条目的目录中选出少量推荐项。这一工程挑战要求将用户和物品映射为共享嵌入空间中的稠密向量,再大规模评估交互概率。

与受计算限制的卷积网络或受带宽限制的 Transformer 不同,推荐模型运行在主要由内存容量决定的工作区间。专为稠密矩阵乘法设计的加速器,例如同时提供数百 TFLOPS 算术吞吐量和 80 GB HBM 的 NVIDIA A100,在执行推荐工作负载时,其算术单元大部分时间处于闲置状态。主导操作并非稠密矩阵乘法,而是对规模可达数 TB 的表进行稀疏聚集。

模式处理需求

推荐系统的核心挑战是处理高基数类别特征。模型必须处理数十亿个账户的用户 ID 和数百万件商品的物品 ID。原始 ID 不具有内在的几何结构。在任何有意义的度量空间中,用户 1042 都不与用户 1043“接近”,神经网络也无法仅凭整数值推断语义关系。

嵌入通过将每个离散 ID 映射为称为嵌入22 的稠密向量来解决表示问题 (Mikolov et al. 2013)。其系统代价在于,每次查找都会成为对一张规模达数十或数百 GB 的表的不规则读取。因此,在第一个稠密前馈层执行之前,推荐模型就会遭遇容量墙和内存带宽瓶颈。

Mikolov, Tomas, Kai Chen, Greg Corrado, and Jeffrey Dean. 2013. “Efficient Estimation of Word Representations in Vector Space.” ICLR abs/1301.3781.

算法结构

DLRM 架构 (Naumov et al. 2019) 将这一工作流程规范化为跨越稠密和稀疏两类计算的四阶段流水线。用户年龄或一天中的时刻等连续特征首先流经底层 MLP,这是一个以稠密矩阵乘法为主、计算密集但内存需求较低的阶段。与此同时,类别 ID 用于索引专用的嵌入表,内存容量墙就在此处出现:

Naumov, Maxim, Dheevatsa Mudigere, Hao-Jun Michael Shi, Jianyu Huang, Narayanan Sundaraman, Jongsoo Park, Xiaodong Wang, et al. 2019. “Deep Learning Recommendation Model for Personalization and Recommendation Systems.” arXiv Preprint arXiv:1906.00091.

例如,为十亿用户存储 128 维向量的嵌入表需要 \(10^9 \times 128 \times 4\) 字节 \(\approx\) 512 GB 的内存。这一阶段内存需求高,但计算量低,因为每次查找都是一次内存复制,不存在算术运算复用。随后,交互层 通过两两点积,将底层 MLP 的稠密激活与聚集得到的稀疏嵌入向量结合起来,以捕捉用户与物品之间的相关性。最后,顶层 MLP 通过前馈层处理拼接后的交互表示,预测点击率等目标概率。这种稠密与稀疏计算的结合,使 DLRM 成为本章的推荐系统标杆案例;section 1.7.3 对由此产生的容量受限特征进行量化。

计算映射与系统影响

DLRM 的计算映射分为两类,分别对不同的硬件子系统施加压力。稠密 MLP 执行标准 GEMM 运算,与 section 1.2.4 中讨论的 MLP 计算映射相同,可由张量核心高效处理。然而,稀疏嵌入查找在本质上与之不同。它们是基于索引的内存聚集操作,算术强度为零,因此在操作层面,单次查找受内存带宽限制。这一操作瓶颈不同于容量约束:表的总大小决定参数能否装入设备内存,而内存总线吞吐量决定各行能够以多快的速度被聚集。由于每个训练样本或请求都会访问不同的一组稀疏行,访问模式的空间局部性和时间局部性都接近于零,使有利于 CNN 和 MLP 的缓存与预取策略失效。

Lighthouse 1.6: DLRM(推荐系统标杆案例)

重要性:DLRM 是受内存容量限制 的工作负载的典型示例。其庞大的嵌入表往往超过单个加速器或服务器的内存容量,因此系统必须先决定这些表存放在哪里,才能优化算术吞吐量。随后,交互层聚集选定的嵌入向量,并将其与稠密特征结合,使容量和不规则数据搬移成为主导约束。这与 CNN(受计算限制)和 Transformer(受内存带宽限制)形成鲜明对比,需要采用不同的硬件和部署方案。Table 7 汇总了这一推荐系统标杆案例的定量特征。

Table 7: DLRM 的系统特征:推荐系统标杆案例的定量特征及其系统影响。包含数十亿条目的嵌入表使模型超出单设备内存容量,形成了机器学习系统铁律未直接涵盖的容量受限运行区间。
属性 值 系统影响
嵌入参数量 25B 参数量 \(\times\) 4 字节;主导模型总大小。
模型大小 100 GB (FP32) 可能超过单个设备的高速内存容量。
约束 内存容量 模型大小 \(> \text{Single GPU Memory}\)。
瓶颈 不规则数据搬移 聚集操作主导稀疏特征处理。
特征 混合(稀疏/稠密) 将内存需求高的查找与计算密集的 MLP 结合起来。

一旦嵌入表的大小超过单个设备的容量,容量而非算术运算就会成为首要的系统约束。ResNet-50(102.4 MB)可以容纳在单个加速器上,而 GPT-3(350 GB)这类稠密语言模型可以容纳在单个多 GPU 节点内,但生产环境中的推荐模型,其嵌入参数规模可达数 TB。用机器学习系统铁律(机器学习系统铁律)来表述,运算次数 \(O\) 和传输量 \(D_{\text{vol}}\) 都不是起决定作用的约束;限制系统的反而是内存的绝对容量,由此形成了一种超出该铁律主要适用范围的情形。

四个嵌入分区通过交换箭头相连,表明稀疏特征查找可能依赖存储在本地分区之外的数据。

DLRM 的嵌入查找可能依赖存储在本地内存分区之外的向量。

因此,这种架构打破了较小稠密模型所满足的单设备假设。系统设计者通过三种不同的架构策略来突破这一容量墙:

  • 缩小表:压缩、哈希或剪枝可以缓解容量压力,但这些技术可能造成长尾用户和物品的信息损失。
  • 迁移表:嵌入可以存放在主机 DRAM 或外部键值存储中,但远程查找会因通过 PCIe 或以太网移动数据而产生较高延迟。
  • 划分表:可以将表分片存储在多个加速器上,使任何单个设备都不必存储完整模型,但此时查找需要跨设备通信。

从架构上看,DLRM 使推荐任务在成为计算优化任务之前,首先成为容量管理挑战。训练时的表划分(模型训练)和硬件加速互连(硬件加速)用于应对这些分布式布局,但最基本的容量估算挑战始于单张表。

三个上下排列的内存条形图:单张物品嵌入表为 51 GB,低于 A100 的 80 GB 容量条;但物品表与用户表合计为 102 GB,超过了该容量,无法再容纳于单个设备。

一张嵌入表可以容纳于 80 GB 的 A100;再增加一张就会突破容量墙。

Napkin Math 1.2: 容量墙
问题:考虑一家商店的推荐系统,其中有 100M 个物品,嵌入维度为 128。仅物品表就需要多少内存?

计算:

  1. 表条目数:100M 个物品。
  2. 向量大小:128 个元素。
  3. 精度:FP32(每个元素 4 字节)。
  4. 表大小:100M 个物品 \(\times\) 128 \(\times\) 4 字节 ≈ 51.2 GB。
  5. 容量占比:51.2 GB \(\div\) 80 GB = 设备容量的 64 percent。
  6. 双表检查:两张表各占 64 percent,合计超过设备容量的 100%。

系统洞见:仅一个特征(物品)的一张嵌入表,就已经消耗了一块 80 GB A100 GPU 容量的 64 percent。再增加一张同样大小的用户表,就意味着这些嵌入表无法继续容纳在单个 80 GB 加速器上,因此需要压缩表、使用设备外内存,或跨设备划分。DLRM 受容量限制:首要的系统问题不是加速器能提供多少 FLOP/s,而是嵌入状态在物理上能够存放在哪里。

一旦这些表无法再容纳于单个设备,稀疏查找就会跨越内存和网络边界。一个请求可能需要由多个设备持有的行,因此承载下游 MLP 的加速器必须等待系统收集这些行。在节点内,这种交换会给加速器互连带来压力;跨节点时,它则会成为全对全集合通信瓶颈。由此产生的架构后果是,推荐模型的内存布局直接决定其网络通信流量,从而为训练和模型服务都带来额外的分布式协调开销。

Checkpoint 1.4: DLRM 与稀疏分散访问

推荐系统对机器资源施加压力的部位与 CNN 或 Transformer 不同。

纵观 MLP、CNN、RNN、Transformer 和 DLRM 式稀疏模型,多样的计算特征最终汇聚到一组精简的共享原语上。稠密矩阵投影、归一化层、跳跃连接和门控机制在这五类架构中反复出现。每个 Transformer 块都包含一个前馈 MLP,而最初为循环单元开发的门控机制,如今负责控制混合专家模型中的路由。这些构建模块具有可迁移性,因为无论归纳偏置如何,它们所解决的数值与优化挑战——梯度传播、激活稳定性和动态路由——始终存在。对于系统工程师而言,识别这些共享原语,有助于判断哪些硬件加速器和编译器优化可以跨工作负载迁移,哪些则必须保持专用。

共享构建模块

Transformer 块复用了若干源自其他架构的思想:来自 MLP 的稠密投影、来自深层 CNN 的残差路径、用于稳定激活的归一化,以及后续变体中类似门控的路由。这五类架构对数据的假设不同,但许多工程问题会反复出现,因此实际问题在于哪些构建模块和优化能够迁移。Table 8 展示了随着架构日趋复杂,这些原语如何逐步积累:每个时期都继承了前一时期的工具,同时增加一种用于应对下一个瓶颈的机制。

Table 8: 跨架构构建模块:起源于某一架构家族、如今在许多现代设计中反复出现的工程原语。每个构建模块都解决一种反复出现的问题(梯度流、激活稳定性、信号路由),但并非每种架构都会使用所有原语。
构建模块 起源架构 解决的问题 当前应用
GEMM MLP 通用函数逼近 所有架构(前馈层)
参数共享 CNN 空间处理效率 Transformer(共享投影)、RNN(跨时间复用权重)
跳跃连接 ResNet(CNN) 深层网络中的梯度流 Transformer、DenseNet、U-Net 以及许多现代深度网络
归一化 CNN(BatchNorm) 激活稳定性 LayerNorm(Transformer)、RMSNorm(均方根归一化)、GroupNorm(通道分组)
门控 LSTM(RNN) 选择性信号路由 Transformer(混合专家路由)、GRU、高速公路网络

这些可迁移的构建模块受到了当时可用硬件的塑造。LeNet-5 (LeCun et al. 1998) 在 CPU 上训练,其网络足够小,只需数 MB 内存即可容纳。AlexNet 在两块 GTX 580 GPU 上训练了拥有 6000 万个参数的网络,将并行卷积映射到图形硬件上 (Krizhevsky et al. 2012)。ResNet-152 (He et al. 2016a) 之所以能够训练,是因为残差连接和批归一化改善了深层网络的优化;它利用了当时已有的 GPU 训练基础设施,而非依赖某个特定的内存容量阈值。Transformer (Vaswani et al. 2017) 在当时的 GPU 上成为实用方案,随后又随着 GPU/TPU 内存带宽和分布式训练基础设施的改进而大幅扩展。这一模式仍在延续:每个构建模块都会利用新出现的计算资源,同时不断触及现有系统的极限。

LeCun, Yann, Léon Bottou, Yoshua Bengio, and Patrick Haffner. 1998. “Gradient-Based Learning Applied to Document Recognition.” Proceedings of the IEEE 86 (11): 2278–324. https://doi.org/10.1109/5.726791.

稠密运算:通用基线

GEMM 是本章所有架构共享的唯一原语。虽然 section 1.2 将 MLP 作为稠密模式处理器进行了考察,但 GEMM 对系统工程的影响远远超出了 MLP。它是每个 Transformer 块中的前馈层、MobileNet 中的 \(1{\times}1\) 逐点卷积、每个 RNN 单元中的输入投影与循环投影,也是每个 DLRM 中的底部 MLP。

MLP 引入了以 GEMM 为主导的计算特征,推动 GPU 厂商开发专用矩阵引擎(Tensor Core)。反向传播算法23的内存访问模式通过交替执行前向传播和反向传播并存储中间激活,塑造了加速器的内存层次结构。MLP 训练率先采用的批处理范式,奠定了现代机器学习基础设施的吞吐量优化方式:将独立样本组合成稠密矩阵,把受内存带宽限制的矩阵—向量乘法转换为受计算能力限制的矩阵—矩阵乘法。这些基础模式贯穿本章考察的所有架构。

稠密连接也确立了后续所有架构都必须面对的成本基线。对于宽度为 \(n\) 的层,参数量和运算量均为 \(\mathcal{O}(n^2)\),因此 GEMM 成为衡量专用架构效率提升的参照点。CNN 以每个位置 \(\mathcal{O}(k^2)\) 的参数量实现空间处理(其中 \(k\) 为卷积核大小);Transformer 以参数效率换取动态计算,其注意力复杂度为 \(\mathcal{O}(S^2)\);而 DLRM 这类稀疏架构则利用嵌入查找来处理会导致稠密层规模急剧膨胀的类别维度。每项创新都代表了一种摆脱稠密连接基线的不同策略,但没有任何架构能摆脱 GEMM 本身——它作为特征变换的主力,在每种架构内部再次出现。

跳跃连接:解决深度问题

参数共享使深度网络在计算上变得可行,但仅有效率并不能解决深层训练中的数值挑战。随着网络加深,反复进行的矩阵乘法和非线性激活导数相乘,会使梯度信号衰减至数值下溢,或放大至浮点溢出。跳跃连接通过引入绕过层变换的加性恒等捷径,来解决这一优化障碍。

深度问题

穿过 \(N_L\) 层的反向传播会反复应用链式法则;梯度计算与反向传播 给出了反向传播和链式法则的形式化推导。对于各层为 \(f_1, f_2, \ldots, f_{N_L}\) 的深度网络,损失 \(\mathcal{L}\) 关于第 1 层权重的梯度为: \[ \frac{\partial \mathcal{L}}{\partial W_1} = \frac{\partial \mathcal{L}}{\partial a_{N_L}} \cdot \frac{\partial a_{N_L}}{\partial z_{N_L}} \cdot \frac{\partial z_{N_L}}{\partial a_{N_L-1}} \cdot \ldots \cdot \frac{\partial z_2}{\partial a_1} \cdot \frac{\partial a_1}{\partial z_1} \cdot \frac{\partial z_1}{\partial W_1} \] 其中,\(z_\ell\) 表示第 \(\ell\) 层的激活前值,\(a_\ell = \sigma(z_\ell)\) 表示该层激活后的输出。梯度变为 \(N_L\) 项的乘积,每一项都依赖于激活函数的导数 \(\sigma'(z_\ell)\)。

梯度消失会在深层架构中造成不易察觉的训练失败。对于 sigmoid 激活函数,其导数为 \(\sigma'(z) = \sigma(z)(1 - \sigma(z))\),最大值为 \(\sigma'(0) = 0.25\)。经过 \(N_L\) 层后,梯度幅值约乘以 \((0.25)^{N_L}\)。在如此剧烈的衰减下,靠前的层只能接收到极其微弱的梯度信号。权重更新变得微乎其微,实际上阻止了这些层的训练。

梯度爆炸则是与梯度消失相对应的失稳现象。层雅可比矩阵中的较大奇异值可能随着深度增加,反复放大某些梯度方向。例如,如果每个雅可比矩阵都将某个共同方向放大约 1.5 倍,那么该分量就会呈指数增长。这种增长会导致数值溢出、NaN(非数)值、极端的参数更新以及训练发散。梯度消失会悄然使学习停滞,而梯度爆炸则会造成灾难性的数值故障。

定量分析:普通深层网络

考虑在 CIFAR-10 上训练一个未采用架构干预措施的普通深层卷积网络。即使使用对正输入导数为 1 的 ReLU 激活,优化仍会随着深度增加而恶化。最初的 ResNet 研究报告称,56 层普通网络在 CIFAR-10 上的测试错误率显著高于 20 层普通网络(约为 13.6%,而后者为 8.8%),这表明,尽管表示能力更强,增加层数仍会妨碍优化 (He et al. 2016a)。

这种退化问题并非过拟合:56 层普通网络的训练错误率也高于 20 层网络,证实失败源于优化障碍,而非泛化能力不足。

为什么 ReLU 有帮助但仍不充分

ReLU 激活(\(\text{ReLU}(z) = \max(0, z)\))的导数为: \[ \text{ReLU}'(z) = \begin{cases} 1 & \text{if } z > 0 \\ 0 & \text{if } z \leq 0 \end{cases} \]

沿激活路径 \((z > 0)\),导数等于 1,从而避免了激活函数引起的梯度衰减。相较于 sigmoid 的这一改进,使 10–20 层网络能够稳定训练。

然而,ReLU 引入了另一种失效模式:死亡神经元。当 \(z \leq 0\) 时,梯度为零,阻断了通过该单元的梯度流。不良的权重初始化或过大的更新,可能使整个训练分布上的激活前值都变为负数,从而永久停用该神经元。此外,ReLU 并不调节权重矩阵本身的谱性质。显著偏离 1 的奇异值,仍会随着深度增加而持续衰减或放大梯度。

残差解决方案

ResNet 块通过跳跃连接引入残差学习,从而改变梯度流。Equation 9 将恒等路径 \(\mathbf{x}\) 加到残差映射 \(\mathcal{F}(\mathbf{x})\) 上: \[ \mathbf{y} = \mathcal{F}(\mathbf{x}) + \mathbf{x} \tag{9}\] 其中,\(\mathcal{F}(\mathbf{x})\) 表示残差函数(通常由带有批归一化和 ReLU 的两个卷积层构成),\(\mathbf{x}\) 则是恒等跳跃连接。

Theorem 1.2: 残差雅可比矩阵的条件性
分析:将网络视为函数的复合 \(\mathbf{x}_{\ell+1} = f_\ell(\mathbf{x}_\ell)\)。根据链式法则,输入处的梯度由各层雅可比矩阵 \(\mathbf{J}_\ell = \frac{\partial f_\ell}{\partial \mathbf{x}_\ell}\) 的乘积给出: \[ \frac{\partial \mathcal{L}}{\partial \mathbf{x}_0} = \frac{\partial \mathcal{L}}{\partial \mathbf{x}_{N_L}} \cdot \prod_{\ell=1}^{N_L} \mathbf{J}_\ell \]

对于普通网络,\(\mathbf{J}_\ell\) 可以是任意矩阵。上界 \(\left\|\prod_\ell \mathbf{J}_\ell\right\|_2 \leq \prod_\ell \|\mathbf{J}_\ell\|_2\) 意味着,一致小于 1 的范数会迫使梯度消失;反之,\(\sigma_{\min}(\prod_\ell \mathbf{J}_\ell) \geq \prod_\ell \sigma_{\min}(\mathbf{J}_\ell)\) 意味着,一致大于 1 的最小奇异值会迫使梯度扩张。对于混合的非正规雅可比矩阵,梯度行为既依赖奇异向量,也依赖特征值,因此仅凭谱半径无法确定梯度行为。

对于 ResNet,层函数为 \(\mathbf{x}_{\ell+1} = \mathbf{x}_\ell + \mathcal{F}(\mathbf{x}_\ell)\),因此雅可比矩阵为: \[ \mathbf{J}_\ell = \mathbf{I} + \frac{\partial \mathcal{F}}{\partial \mathbf{x}_\ell} \] 其中,\(\mathbf{I}\) 是单位矩阵。如果 \(\varepsilon_\ell=\|\mathcal{F}'_\ell\|_2<1\),则有 \(1-\varepsilon_\ell \leq \sigma_{\min}(\mathbf{J}_\ell) \leq \sigma_{\max}(\mathbf{J}_\ell) \leq 1+\varepsilon_\ell\)。因此,残差雅可比矩阵较小的块接近恒等映射,并且局部条件良好。在许多块之间,这些偏差仍可能累积,因此跳跃连接能够改善梯度流,但并不能保证单位增益,也不能防止相互抵消。

在反向传播期间,梯度通过这一加法运算传播: \[ \frac{\partial \mathcal{L}}{\partial \mathbf{x}} = \frac{\partial \mathcal{L}}{\partial \mathbf{y}} \cdot \frac{\partial \mathbf{y}}{\partial \mathbf{x}} = \frac{\partial \mathcal{L}}{\partial \mathbf{y}} \cdot \frac{\partial (\mathcal{F}(\mathbf{x}) + \mathbf{x})}{\partial \mathbf{x}} \]

应用链式法则: \[ \frac{\partial \mathcal{L}}{\partial \mathbf{x}} = \frac{\partial \mathcal{L}}{\partial \mathbf{y}} \cdot \left(\frac{\partial \mathcal{F}(\mathbf{x})}{\partial \mathbf{x}} + \mathbf{I}\right) = \frac{\partial \mathcal{L}}{\partial \mathbf{y}} \cdot \mathcal{F}'(\mathbf{x}) + \frac{\partial \mathcal{L}}{\partial \mathbf{y}} \]

梯度被分解为两个相加的项。即使残差变换 \(\frac{\partial \mathcal{L}}{\partial \mathbf{y}}\mathcal{F}'(\mathbf{x})\) 发生衰减,恒等项仍会将 \(\frac{\partial \mathcal{L}}{\partial \mathbf{y}}\) 直接传递到更早的层。尽管残差分支可能与恒等信号发生部分干涉,但保持 \(\|\mathcal{F}'(\mathbf{x})\|\) 较小,可以确保块的雅可比矩阵保持接近单位矩阵,并限制其条件数。这条加性路径提供了贯穿网络的直接梯度捷径,但并不保证在任意深度下都能保持精确的单位增益。

穿过多个块的梯度流

穿过 \(N_L\) 个残差块后,梯度变为: \[ \frac{\partial \mathcal{L}}{\partial \mathbf{x}_0} = \frac{\partial \mathcal{L}}{\partial \mathbf{x}_{N_L}} \cdot \prod_{\ell=1}^{N_L} \left(\mathcal{F}'_\ell(\mathbf{x}_\ell) + \mathbf{I}\right) \]

每个因子 \((\mathcal{F}'_\ell + \mathbf{I})\) 都包含恒等项,因此当残差分支的雅可比矩阵较小时,该因子就会保持接近单位矩阵。普通网络将任意的层雅可比矩阵相乘,而 ResNet 将这些接近单位矩阵的因子相乘。偏差仍可能累积,但这种结构改善了条件性,有助于使 100 层及以上的网络也能够训练。

56 层网络上的实证验证

实证结果证实了这种理论上的条件改善。在最初的 CIFAR-10 实验中,一个 56 层残差网络达到了约 7.0% 的测试错误率,逆转了普通网络中出现的退化现象,并优于其 20 层对应模型 (He et al. 2016a)。恒等捷径为梯度反向传播和表征细化提供了畅通的路径,使更深的模型能够发挥其容量优势。并不存在某个统一的深度阈值,使跳跃连接突然成为必需;可训练性还取决于初始化、归一化、优化器动态特性以及模块架构 (He et al. 2016b)。

He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. 2016a. “Deep Residual Learning for Image Recognition.” 2016 IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 770–78. https://doi.org/10.1109/cvpr.2016.90.
He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. 2016b. “Identity Mappings in Deep Residual Networks.” Computer Vision – ECCV 2016, 630–45. https://doi.org/10.1007/978-3-319-46493-0_38.

虽然跳跃连接解决了梯度的条件性问题,但它也带来了具体的硬件成本。计算 \(\mathbf{y} = \mathcal{F}(\mathbf{x}) + \mathbf{x}\) 时,输入张量 \(\mathbf{x}\) 必须在分支 \(\mathcal{F}(\mathbf{x})\) 中所有操作的整个执行期间驻留在内存中。这一延长的存活时间窗口增加了前向传播期间加速器 HBM 中的激活内存峰值,并且除非使用激活检查点,否则还需要保留 \(\mathbf{x}\) 以供反向传播使用。此外,逐元素加法受内存带宽限制:每加载一个值仅执行一次加法(算术强度 \(\approx 0.5\) FLOP/byte),使未融合的残差合并操作转化为内存停顿。

残差连接稳定了反向梯度路径,但并不约束中间激活在前向传播中的尺度。随深度增长而不受约束的方差仍可能使层输入不稳定,因此需要一种互补原语:归一化。

归一化:稳定深层网络中的激活

归一化是跳跃连接在前向传播中的配套机制:残差路径维持反向梯度流,而归一化稳定中间激活的分布。这一原语最初以 CNN 中的批归一化形式确立24 (Ioffe and Szegedy 2015),随后演变为序列模型中的层归一化,并进一步简化为用于大语言模型的 RMSNorm25。

批归一化:定义与公式

批归一化在训练期间,使用针对每个特征或通道在小批量上计算的统计量对激活进行标准化。对于全连接层的激活,归约轴是批量维度。对于卷积激活,实现会在批量和空间位置两个范围上计算每个通道的统计量(\(B \times H \times W\))。对于某一层激活的小批量 \(\mathcal{B} = \{x_1, \ldots, x_B\}\),这一变换分为两个阶段。

首先,计算批统计量: \[ \mu_{\mathcal{B}} = \frac{1}{B}\sum_{i=1}^{B} x_i \qquad \sigma_{\mathcal{B}}^2 = \frac{1}{B}\sum_{i=1}^{B} (x_i - \mu_{\mathcal{B}})^2 \]

然后,在该批量上进行归一化,并应用可学习的缩放和平移。equation 10 中的归一化步骤对激活进行中心化和缩放,而 equation 11 应用可学习参数,使网络在恒等变换为最优选择时能够恢复该变换: \[ \hat{x}_i = \frac{x_i - \mu_{\mathcal{B}}}{\sqrt{\sigma_{\mathcal{B}}^2 + \epsilon}} \tag{10}\] \[ y_i = \gamma \hat{x}_i + \beta \tag{11}\]

参数 \(\gamma\)(缩放)和 \(\beta\)(平移)在训练期间学习,而 \(\epsilon\)(通常为 \(10^{-5}\))用于防止除以零。仿射变换恢复了通过学习调整缩放和平移的灵活性,但固定的 \(\gamma\) 和 \(\beta\) 无法精确逆转每个批量中不断变化的统计量。归一化通过防止中间激活急剧增大而进入非线性函数的饱和区间,允许使用更大的学习率,从而相较于未归一化的网络加快收敛。

Theorem 1.3: 归一化的雅可比矩阵条件性
分析:归一化通过改善层的雅可比矩阵的条件性来稳定训练。对于当前批量,考虑归一化输出相对于输入的梯度: \[ \frac{\partial \hat{x}_i}{\partial x_j} = \frac{1}{\sqrt{\sigma_{\mathcal{B}}^2 + \epsilon}} \left( \delta_{ij} - \frac{1}{B} - \frac{(x_i - \mu_{\mathcal{B}})(x_j - \mu_{\mathcal{B}})}{B(\sigma_{\mathcal{B}}^2 + \epsilon)} \right) \] 其中,\(\delta_{ij}\) 是克罗内克 delta。该雅可比矩阵将批量内的样本耦合起来,其尺度由 \(1/\sqrt{\sigma_{\mathcal{B}}^2+\epsilon}\) 决定;后续仿射变换的缩放系数 \(\gamma\) 会乘到该矩阵上。它存在与批量整体平移不变性相关的零方向,因此不存在诸如 \([0.5,2.0]\) 这样的普适正特征值界限。

从实证上看,批归一化通过标准化中间尺度改善了优化,但它本身并不能防止整个网络中的梯度消失或爆炸。其定量效果取决于架构、批统计量、优化过程和参数化方式,而不是某个普适的两倍至四倍梯度范围。

层归一化:架构独立性

虽然批归一化使训练深得多的 CNN 成为可能,但它也给分布式系统和序列建模带来了严重约束。在分布式训练中,计算真实的小批量统计量需要通过 PCIe 或 NVLink 在加速器节点间执行全归约操作,为每个归一化层增加通信延迟。如果改为在每个加速器的小批量上进行本地计算,带噪声的经验统计量又会使优化不稳定。此外,批归一化在处理变长序列或逐词元自回归生成时,无法避免复杂的填充掩码和训练与服务偏差。层归一化通过沿特征维度而非批量维度进行归一化,解决了这些局限 (Ba et al. 2016)。

Ba, Jimmy Lei, Jamie Ryan Kiros, and Geoffrey E. Hinton. 2016. “Layer Normalization.” arXiv Preprint arXiv:1607.06450.

对于具有 \(d_{\text{model}}\) 个特征的输入向量 \(\mathbf{x} \in \mathbb{R}^{d_{\text{model}}}\): \[ \mu_{\text{LN}} = \frac{1}{d_{\text{model}}}\sum_{i=1}^{d_{\text{model}}} x_i \qquad \sigma_{\text{LN}}^2 = \frac{1}{d_{\text{model}}}\sum_{i=1}^{d_{\text{model}}} (x_i - \mu_{\text{LN}})^2 \]

Equation 12 定义了完整的层归一化操作,其中 \(\odot\) 表示逐元素乘法: \[ \text{LayerNorm}(\mathbf{x}) = \frac{\mathbf{x} - \mu_{\text{LN}}}{\sqrt{\sigma_{\text{LN}}^2 + \epsilon}} \odot \boldsymbol{\gamma} + \boldsymbol{\beta} \tag{12}\]

层归一化独立地对每个词元或样本进行归一化。计算在加速器的片上 SRAM 和寄存器中本地执行,无需跨样本或跨设备通信。这种独立性使层归一化成为 Transformer 的标准选择,因为其序列长度各异,且自回归生成在推理时逐个计算词元。

对比分析:何时使用各类变体

归一化变体的选择体现了不同的硬件与运行权衡。Table 9 总结了其核心属性。BatchNorm 在维护学习得到的缩放和平移参数的同时,还维护非学习的运行均值与方差缓冲区;LayerNorm 在运行时为每个样本动态计算统计量,从而消除了有状态的运行统计量缓冲区。

Table 9: 归一化变体对比:不同归一化技术在计算效率、对批量大小的敏感性和架构兼容性之间进行权衡。LLaMA 系列及其他高效 Transformer 架构 (Touvron, Lavril, et al. 2023; Touvron, Martin, et al. 2023) 使用的 RMSNorm (Zhang and Sennrich 2019) 省去了均值中心化:\(\text{RMSNorm}(\mathbf{x}) = \mathbf{x} / \sqrt{\frac{1}{d_{\text{model}}}\sum_i x_i^2 + \epsilon} \cdot \boldsymbol{\gamma}\)。
特征 BatchNorm LayerNorm RMSNorm
归一化轴 批量,以及 CNN 中的空间位置 特征维度 特征维度
对批量大小的依赖 高(小批量时噪声较大) 无 无
典型用例 CNN、视觉模型 Transformer、RNN LLaMA、高效 Transformer
计算成本 较高(均值 + 方差) 较高(均值 + 方差) 较低(仅均方根)
训练/推理 不同(运行统计量) 相同 相同

归一化的计算特征由其算术强度决定。由于归一化对大型激活张量执行逐元素操作,其执行受内存带宽限制,而非计算能力限制。标准 LayerNorm 需要在 SRAM 中沿隐藏维度 \(d_{\text{model}}\) 进行两次归约遍历:第一次累加以求取均值 \(\mu_{\text{LN}}\),第二次计算方差 \(\sigma_{\text{LN}}^2\)。RMSNorm 消除了均值中心化步骤,将该操作简化为一次平方和归约。这一次归约遍历使内存流量减半,并允许更紧密的内核融合,从而带来了在各类 Transformer 推理工作负载中报告的 7–64% 的加速。

在运行层面,BatchNorm 需要在训练模式(计算小批量统计量)和推理模式(应用训练期间累积的运行统计量)之间显式切换。运行统计量与部署数据分布之间的不匹配,是训练与服务偏差的常见来源。LayerNorm 和 RMSNorm 在训练与推理期间执行相同的计算,消除了运行统计量缓冲区,并确保不同部署环境中的一致性。

门控:控制信息流

跳跃连接和归一化分别通过改善梯度流和激活方差,解决与深度相关的稳定性问题。门控则应对另一项挑战:根据输入上下文,有选择地在网络中路由信息。

门控起源于循环网络,其中简单的循环结构在长时间序列上存在严重的梯度退化。LSTM26 (Hochreiter and Schmidhuber 1997) 和 GRU27 (Cho et al. 2014) 通过引入门来解决这一问题:这些由参数加权的变换充当可微分阀门,用于保护、更新或丢弃已存储的状态。

Hochreiter, Sepp, and Jürgen Schmidhuber. 1997. “Long Short-Term Memory.” Neural Computation 9 (8): 1735–80. https://doi.org/10.1162/neco.1997.9.8.1735.
Bahdanau, Dzmitry, Kyunghyun Cho, and Yoshua Bengio. 2015. “Neural Machine Translation by Jointly Learning to Align and Translate.” International Conference on Learning Representations (ICLR).

门控可推广到循环结构之外,成为依赖数据的条件路由的基础机制。在前馈结构中,高速公路网络使用门控,在变换与恒等旁路之间动态插值,直接启发了残差捷径。在序列处理中,注意力将门控扩展至整个时间上下文:编码器—解码器注意力 (Bahdanau et al. 2015) 计算输入表征上的动态路由分布。在 Transformer 中,softmax 注意力权重充当依赖数据的路由系数,决定特征如何跨词元聚合;而混合专家架构则将门控扩展为将词元动态分派到专门的前馈子网络。

综合:Transformer 如何重新组合所有原语

现代 Transformer 架构将全部四种共享原语整合到一个统一模块中。如 figure 11 所示,残差路径包裹每个子层,以维持梯度在深层堆叠中的流动。稠密 GEMM 投影执行多头注意力和前馈子网络内的特征变换。LayerNorm(或 RMSNorm)在每次投影之前稳定激活。最后,注意力 softmax 权重对词元位置之间的信息路由进行动态门控。

\begin{tikzpicture}[line join=round,font=\small\sffamily]
\tikzset{%
  Line/.style={line width=1.0pt,black!50,text=black},
  Box/.style={align=center,
    inner xsep=2pt,
    node distance=2,
    draw=BlueLine,
    line width=0.75pt,
    fill=BlueL,
    text width=24mm,
    minimum width=24mm, minimum height=10mm
  },
  op/.style={circle, draw=GreenLine, minimum size=9mm,fill=GreenL,line width=0.75pt},
  >={Latex[length=2mm]},line/.style={-latex, thick},
do path picture/.style={%
    path picture={%
      \pgfpointdiff{\pgfpointanchor{path picture bounding box}{south west}}%
        {\pgfpointanchor{path picture bounding box}{north east}}%
      \pgfgetlastxy\x\y%
      \tikzset{x=\x/2,y=\y/2}%
      #1
    }
  },
plus/.style={do path picture={
    \draw [black,line cap=round, line width=1pt] (-3/5,0) -- (3/5,0) (0,-3/5) -- (0,3/5);
  }}
}
%
\node[Box] (in) {权重层};
\node[Box, right=5 of in] (hidden) {权重层};
\node[op] (relu1) at ($(in)!0.5!(hidden)$) {ReLU};
\node[circle,draw,minimum size=7mm,node distance=1.65,right=of hidden,plus,
draw=BrownLine,fill=BrownL,line width=0.75pt] (add) {};
\node[op, below=0.7 of add] (relu2) {ReLU};
%
\draw[Line,-latex] (in) -- (relu1);
\draw[Line,-latex] (relu1) -- (hidden);
\draw[Line,-latex] (hidden) -- (add);
\draw[Line,-latex] (add) -- (relu2);
\draw[Line,-latex] (relu2) -- ++(1.7,0);
%  Feedback (identity)
\draw[Line,latex-] (in.west) --coordinate(SR) ++(-1.5,0) node[left] {$\mathbf{x}$};
\draw[Line,-latex] (SR) --++(0,0.9)  -| node[pos=0.25,above]{$\mathbf{x}$ 恒等}(add);
%
\node[below=2pt of relu2] {$\mathcal{F}(\mathbf{x}) + \mathbf{x}$};
\node[below=2pt of relu1] {$\mathcal{F}(\mathbf{x})$};
\end{tikzpicture}
Figure 11: 残差连接模块:跳跃连接实现 \(\mathbf{y} = \text{ReLU}(\mathcal{F}(\mathbf{x}) + \mathbf{x})\),创建一条在最终非线性变换之前绕过权重层的恒等捷径。在反向传播期间,梯度同时流经残差路径(通过 \(\mathcal{F}'(\mathbf{x})\))和恒等路径(通过最终非线性变换之前的 \(\mathbf{I}\)),帮助梯度即使在超过 100 层的网络中也能到达早期层。这种架构模式使极深的残差 CNN 成为可能,并成为 Transformer 模块和许多其他现代架构的核心。

从 RNN 到 Transformer 的转变,以可并行的全互连注意力替代了顺序循环步骤之间的依赖,将词元交互所需的顺序操作深度从 \(\mathcal{O}(S)\) 步降至 \(\mathcal{O}(1)\) 步。这一架构转变最大限度地提高了 GPU 和 TPU 等大规模并行加速器的硬件占用率;在这些设备上,如果受到顺序依赖约束,数千个算术单元就会闲置。其他构建模块则直接沿用:GEMM、跳跃连接和归一化在所有架构家族中仍然至关重要。

这种可迁移性也延伸到了现代变体。视觉 Transformer28 将 Transformer 适配到图像,同时保留了全部四种构建模块 (Dosovitskiy et al. 2021)。GPT-3 通过交替使用稠密注意力和局部带状稀疏注意力,扩展了这些 Transformer 模式,同时依赖完全相同的一组原语 (Brown et al. 2020)。实际实现中的挑战和优化将在 模型压缩 中探讨。

Brown, Tom B., Benjamin Mann, Nick Ryder, Melanie Subbiah, Jared Kaplan, Prafulla Dhariwal, Arvind Neelakantan, et al. 2020. “Language Models Are Few-Shot Learners.” Advances in Neural Information Processing Systems 33: 1877–901. https://doi.org/10.48550/arxiv.2005.14165.

Table 10 对比了四类架构使用这些核心原语的方式。Transformer 保留了所有架构共有的稠密 GEMM 操作,同时通过注意力引入依赖内容的全互连归约,将 MLP 的广播操作与更具动态性的架构中的收集和归约操作相结合。

Table 10: 各类架构的原语使用情况:每种架构都使用 GEMM,但它们在内存访问模式、数据移动(从广播到收集与归约)以及并行性方面有所不同。Transformer 将稠密分块 QKV 访问与注意力特有的归约相结合,因此会同时对 GEMM 单元和归约路径施加压力。
原语类型 MLP CNN RNN Transformer
计算 稠密 GEMM 卷积 顺序 GEMM GEMM + 注意力
内存访问 顺序 跨步 顺序 + 状态 分块 QKV 数据流
数据移动 广播 滑动窗口 时间维度广播 收集 + 归约
并行性 高 高 低(时间依赖) 高(位置)

对于系统工程师而言,这种构建模块视角区分了可迁移的优化与架构专用优化。GEMM 分块和混合精度计算使所有架构受益。跳跃连接的内存管理适用于任何残差网络。归一化内核融合对 CNN 和 Transformer 都有帮助。注意力专用优化仍与注意力的内存访问模式紧密相关,但即使这些优化也建立在相同的底层 GEMM 和内存访问原语之上。为理解这些优化为何能够迁移,section 1.9 将共享层转换为机器实际执行的底层原语。

计算原语

框架和编译器并不直接执行高层的层抽象;它们将神经网络转换为一组精简的底层计算原语。ResNet-50 的一次前向传播执行数十亿次乘加运算;Transformer 注意力模块通过片上存储层次结构传输数 GB 的数据;推荐模型在 TB 级嵌入表上分散执行随机查找。尽管架构存在这些差异,硬件上的物理工作负载最终都归结为三个原语领域:稠密算术、内存访问轨迹,以及核心间或设备间的数据移动。分离出这些原语,就能揭示物理瓶颈——算术强度、内存带宽和互连延迟——这些瓶颈决定了 硬件加速 中详述的加速器设计与编译器优化。

核心计算原语

核心原语决定了一种架构要求硬件优化哪种执行模式:稠密张量运算、重复的局部复用,或依赖输入的路由。矩阵乘法、滑动窗口操作和动态计算在各类模型中反复出现,因为它们在转换为芯片上的底层操作时,各自保留了独特的执行特征。它们在工程意义上属于原语:进一步分解会抹去硬件单元和编译器必须优化的性能特征。

矩阵乘法是稠密张量运算路径。将激活矩阵乘以权重矩阵,会计算跨特征维度的线性组合(回顾 section 1.2.3 中的参考 MLP 层)。这一路径在现代工作负载中占据主导地位:MLP 直接执行矩阵乘法以实现全连接投影,CNN 将卷积转换为底层矩阵乘法,而 Transformer 则依赖矩阵乘法实现查询、键、值投影及前馈网络。Figure 12 展示了底层转换过程如何将滑动窗口的空间局部性映射为标准的行主序矩阵乘积。

\begin{tikzpicture}[line join=round,font=\sffamily\small]
\tikzset{
Line/.style={line width=1.0pt,VioletLine,text=black},
  mymatrix/.style={
    matrix of nodes,
    nodes={
      draw,
      fill=orange!40,
      minimum size=8mm,
      text centered,
      execute at begin node=\strut, % za vertikalno poravnanje
      text depth=0.25ex,
      text height=1.25ex,
    },
    column sep=-\pgflinewidth,
    row sep=-\pgflinewidth,
    nodes in empty cells
  }
}
%MA1
\begin{scope}[local bounding box=MA1,shift={(0,0)}]
    \matrix[mymatrix,
  column 1/.style={nodes={fill=cyan!30}},
  column 2/.style={nodes={fill=cyan!30}},
  column 3/.style={nodes={fill=cyan!30}},
  column 4/.style={nodes={fill=cyan!30}},](M1){%
1&  2 &4&5&10&11&13&14 \\
2& 3  &5&6&11&12&14&15 \\
4& 5  &7&8&13&14&16&17 \\
5& 6  &8&9&14&15&17&18 \\
      };
\node[draw=red,inner sep=-2pt,rounded corners=8pt,
yshift=0mm,fill=none,fit=(M1-1-1)(M1-1-4),line width=1.5pt](F1){};
\node[draw=red,inner sep=-2pt,rounded corners=8pt,
yshift=0mm,fill=none,fit=(M1-2-5)(M1-2-8),line width=1.5pt](F3){};
\node[above=3pt of M1]{转换后的 GEMM};
\end{scope}
%MA2
\begin{scope}[local bounding box=MA2,shift={($(MA1.north west)+(-3,-1)$)}]
    \matrix[mymatrix,
 nodes={fill=green!40}](M2){%
1& 2 \\
3& 4 \\
      };
\node[draw=red,inner sep=-2pt,rounded corners=8pt,
yshift=0mm,fill=none,fit=(M2-1-1)(M2-2-2),line width=1.5pt](F5){};
\end{scope}
%MA3
\begin{scope}[local bounding box=MA3,shift={($(MA1.south west)+(-3,0.5)$)}]
    \matrix[mymatrix,
 nodes={
      fill=yellow!30}](M3){%
5& 6 \\
7& 8 \\
      };
\node[below=3pt of M3]{滤波器核};
\end{scope}
%MA4
\begin{scope}[local bounding box=MA4,shift={($(M2-2-1.north west)+(-2.75,0.5)$)}]
    \matrix[mymatrix,
 nodes={
      fill=cyan!30}](M4){%
1& 2&3 \\
4& 5&6 \\
7& 8&9 \\
      };
\node[draw=red,inner sep=-2pt,rounded corners=8pt,
yshift=0mm,fill=none,fit=(M4-1-1)(M4-2-2),line width=1.5pt](F2){};
\node[below=3pt of M4]{输入特征图};
\end{scope}
%MA5
\begin{scope}[local bounding box=MA4,shift={($(M3-2-1.north west)+(-2.75,-0.5)$)}]
    \matrix[mymatrix,
 nodes={ fill=orange!40}](M5){%
10& 11&12 \\
13& 14&15 \\
16& 17&18 \\
      };
\node[draw=red,inner sep=-2pt,rounded corners=8pt,
yshift=0mm,fill=none,fit=(M5-1-2)(M5-2-3),line width=1.5pt](F4){};
\end{scope}
%MA6
\begin{scope}[local bounding box=MA6,shift={($(MA1.east)+(1.98,0)$)}]
    \matrix[mymatrix,
 nodes={fill=green!40},
row 5/.style={nodes={fill=yellow!30}},
row 6/.style={nodes={fill=yellow!30}},
row 7/.style={nodes={fill=yellow!30}},
row 8/.style={nodes={fill=yellow!30}}](M6){%
1\\ 2 \\ 3\\ 4 \\ 5\\ 6\\7\\8\\
      };
\node[draw=red,inner sep=-2pt,rounded corners=8pt,
yshift=0mm,fill=none,fit=(M6-1-1)(M6-4-1),line width=1.5pt](F6){};
\end{scope}
%%
\draw[Line,-latex](F5)--++(0,2.5)-|(F6);
\draw[Line,-latex](F2)--++(0,1.2)-|(F1);
\draw[Line,-latex](F4)--++(0,-2.0)-|(F3);
\node[font=\huge] at($(M1.east)!0.5!(M6.west)$){$\times$};
\coordinate(SR)at($(M2-2-2.south east)!0.65!(M3-1-2.north east)$);
\node[single arrow, draw=black,thick, fill=VioletL,
      minimum width = 20pt, single arrow head extend=3pt,
      minimum height=11mm]at($(SR)!0.5!(M1.west)$) {};
\end{tikzpicture}
Figure 12: im2col 变换:通过将图像块展开为稠密矩阵,将卷积转换为 GEMM。两个 \(3{\times}3\) 输入特征图产生四个滑动窗口位置,此处表示为一个 \(4{\times}8\) 矩阵的各行;两个 \(2{\times}2\) 滤波器核堆叠成一个 \(8{\times}1\) 列向量。二者的乘积得到四个输出位置。展开转换可以利用经过优化的矩阵计算内核,但会增加内存占用,增幅取决于卷积核大小、步幅、填充和实现方式,因此其性能收益取决于工作负载。

im2col29(图像转列)技术将滑动窗口卷积转换为稠密 GEMM。通过将每个感受野块展开为矩阵的一行,并将滤波器权重堆叠为列,im2col 使卷积层能够使用 cuBLAS、MKL 和 OpenBLAS 等成熟且经过厂商调优的 GEMM 库执行。

这种展开转换带来了明确的以内存换计算的权衡。形状为 \((B, C_{\text{in}}, H, W)\) 的批量输入张量被展开为形状为 \([(B \cdot H_{\text{out}} \cdot W_{\text{out}}) \times (K^2 \cdot C_{\text{in}})]\) 的矩阵,而卷积滤波器被重塑为 \([(K^2 \cdot C_{\text{in}}) \times C_{\text{out}}]\)。二者的乘积得到形状为 \([(B \cdot H_{\text{out}} \cdot W_{\text{out}}) \times C_{\text{out}}]\) 的输出矩阵。对于卷积核大小为 \(K\)、步幅为 1 的卷积,重叠感受野共享的输入像素在内存中最多会被复制为 \(K^2\) 份,从而增加内存占用和 DRAM 流量,除非通过融合或分块直接在片上 SRAM 中处理。

结构化稀疏性和非结构化稀疏性见 剪枝;硬件感知的稀疏执行及算法与硬件协同设计见 硬件加速。

滑动窗口操作代表局部复用路径。原生滑动窗口执行方式不在内存中物化重复的缓冲区,而是让紧凑的滤波器核在输入张量上滑动,执行局部模板计算。加速器通过专门的数据流缓冲机制利用这一结构。例如,TPU 将计算映射到二维脉动阵列,30其中激活值和权重同步流经由乘加处理单元组成的网格。直接在相邻寄存器之间传递数据,可以避免每次算术运算都往返访问片外内存。

动态计算代表自适应路由路径。在稠密 Transformer 注意力中,查询与键的交互权重随输入词元而变化,但底层张量形状和矩阵操作仍然是静态且规则的。相比之下,稀疏注意力、混合专家(MoE)门控和动态图执行会引入依赖数据的控制流与运行时张量维度。这种动态执行对传统的静态内存分配和并行任务分派提出了挑战。

生产架构会组合使用这些执行路径。Transformer 块使用形状为 \([S, d_{\text{model}}] \times [d_{\text{model}}, d_{\text{proj}}]\) 的稠密 GEMM 进行特征投影,计算 \(S \times S\) 的注意力分数,并可选择在专家子网络之间进行动态路由。然而,理论上的峰值算术吞吐量并不保证实际性能:如果内存子系统无法以匹配的速率提供操作数,硬件执行单元就会持续处于数据供给不足的状态。

内存访问原语

内存访问的速度和可预测性决定了加速器利用率。即使矩阵乘法引擎具备数百 teraFLOPs 的计算能力,若数据无法足够快地穿过内存层次结构,它仍会停顿。片上算术运算只需个位数个时钟周期即可完成,而从片外 DRAM 获取一个操作数则需要数百个周期。

内存访问模式分为三类——顺序访问、跨步访问和随机访问——它们决定了硬件能够以多高的效率预取、缓存和合并内存请求。由于跨封装边界传输数据所消耗的功率远高于 ALU 运算,内存访问模式不仅决定执行延迟,也决定能耗预算。

Systems Perspective 1.2: 数据移动的能耗
一条核心系统原则是:移动数据比对数据进行计算的能耗更高。一次浮点乘加运算的能耗约为 1–5 pJ,具体取决于工艺节点(例如,45 nm 工艺下约为 4.6 pJ (Horowitz 2014)),而在同一参考模型中,从片外 DRAM 获取一个 32 位操作数的能耗为数百 pJ。即使采用保守估计,片外 DRAM 访问的能耗也是算术运算的数十至数百倍,这解释了为什么决定实际效率的不仅是 FLOP 数量,还有内存访问模式。

从能耗角度重新审视前述架构:MLP 的数据复用率较低(每个样本都需要加载一次各个权重),因此其能耗主要由 DRAM 流量决定。CNN 在各个空间位置复用滤波器权重,将加载成本分摊到 \(H \times W\) 次应用中;使其受计算限制的局部性也使其具备较高的能效。RNN 跨时间步复用权重(时间复用率高),但每一步都要重复付出隐藏状态读写的代价。Transformer 将成对分数计算与键值移动相结合,使稠密全序列注意力的计算量呈二次增长;实现方式和分块策略决定了辅助内存流量及能耗。这些能耗特征与 table 3 中的瓶颈列直接对应。

这一原则是后续优化策略的基础:量化与精度 展示了量化如何减少每个数值需要移动的位数,剪枝如何消除不必要的数据移动,以及分块如何将工作集保留在速度更快、能耗更低的缓存中。

顺序访问可提供最高的有效带宽。在批量 MLP 矩阵乘法过程中,硬件以流式方式读取连续的权重行和激活向量。现代 DRAM 架构利用面向连续地址的突发模式传输,充分利用可用接口带宽(HBM 子系统可达到每秒数 TB),同时硬件预取器会预测后续缓存行。编译器通过分配连续内存块,并使张量步长与硬件缓存行对齐,针对这一模式进行优化。

当内存请求以固定间隔跳过不连续地址时,就会发生跨步访问。在未采用 im2col 变换的标准卷积层中,沿空间维度执行卷积需要访问间隔为特征图行步长的输入。跨步访问会读取整个缓存行,却只使用其中一部分字节,从而降低内存吞吐量。编译器通过重排循环,或将跨步切片打包到共享内存中的连续临时缓冲区,来减轻这一损失。

随机访问会造成最严重的内存瓶颈。在推荐模型的嵌入表中,稀疏特征 ID 索引 GB 级或 TB 级表中的任意行。这些不可预测的查找使硬件预取器失效,将 DRAM 突发传输事务碎片化,并导致较高的缓存未命中率。稠密 Transformer 注意力则呈现出不同的特征:虽然注意力权重取决于内容,但底层查询、键和值向量存储在连续张量中。优化后的注意力计算内核通过片上 SRAM 对这些稠密矩阵进行分块处理,完全避免了对 DRAM 地址的随机访问。

Table 11 量化了这些内存访问模式如何决定各模型家族中参数和激活值存储的规模增长规律。

Table 11: 内存访问复杂度:不同神经网络架构表现出不同的内存访问模式和存储需求,进而影响系统性能与可扩展性。参数存储取决于模型维度,而激活值存储则构成显著的运行时开销。Transformer 的 \(\mathcal{O}(B S^2)\) 项描述的是朴素实现中物化的注意力分数;分块的精确注意力计算内核可以避免保留这一完整矩阵。
架构 对输入的依赖关系 参数存储 激活值存储 规模增长特征
MLP 线性 \(\mathcal{O}(N_{\text{in}} \times d_{\text{width}})\) \(\mathcal{O}(B \times d_{\text{width}})\) 可预测
CNN 相对于分辨率为常数 \(\mathcal{O}(K^2 C_{\text{in}} C_{\text{out}})\) \(\mathcal{O}(B \times H_{\text{img}} \times W_{\text{img}} \times C)\) 高效
RNN 线性 \(\mathcal{O}(d_{\text{hidden}}^2)\) \(\mathcal{O}(B \times S \times d_{\text{hidden}})\) 具有挑战性
Transformer 注意力呈二次增长 每个块为 \(\mathcal{O}(d_{\text{model}}^2 + d_{\text{model}} d_{\text{ff}})\) 注意力为 \(\mathcal{O}(B \times S^2)\),另加 \(\mathcal{O}(B S d_{\text{model}})\) 的激活值 存在问题

其中:

  • \(N_{\text{in}}\):输入大小
  • \(d_{\text{width}}\):层宽度
  • \(B\):批量大小
  • \(K\):卷积核大小
  • \(C\):通道数
  • \(C_{\text{in}}, C_{\text{out}}\):输入和输出通道数
  • \(H_{\text{img}}\):输入特征图高度(CNN)
  • \(W_{\text{img}}\):输入特征图宽度(CNN)
  • \(d_{\text{hidden}}\):RNN 隐藏状态维度
  • \(S\):序列长度
  • \(d_{\text{model}}\):Transformer 模型维度

这些内存规模增长特性决定了数据复用机会和缓存行为。在 CNN 中,空间复用使每个输入像素能够参与多次重叠的滤波器计算(对于 \(K \times K\) 卷积核,为 \(K^2\) 次),从而使 L1、L2 和共享内存能够通过循环分块分摊 DRAM 加载成本。相反,不使用批处理的 MLP 会为单个输入向量重新加载整个权重矩阵,数据复用率极低,使处理器受限于带宽供给不足。

工作集大小——执行单元同时需要的数据量——决定了一项操作所需的数据能否容纳在高速片上内存中。MLP 层的工作集通常可容纳在数百 KB 内,完全驻留于片上 SRAM。相比之下,Transformer 中的全序列注意力会物化规模按 \(\mathcal{O}(B \cdot S^2)\) 增长的中间注意力矩阵,对于长序列,这些矩阵很容易超出片上 SRAM 容量并溢出到高带宽 DRAM,除非采用在线 softmax 分块进行融合。

table 11 定义了内存规模增长规律,而 table 12 则对比了四种参考架构由此产生的算术运算需求、并行化结构及主要硬件瓶颈。

Table 12: 计算复杂度比较:主要神经网络架构的规模增长行为和资源需求。变量:\(d_{\text{in}}\) = 输入维度,\(d_{\text{out}}\) = 输出维度,\(d_{\text{model}}\) = Transformer 模型维度,\(d_{\text{hidden}}\) = RNN 隐藏状态维度,\(k\) = 卷积核大小,\(c\) = 通道数,\(H_{\text{img}}, W_{\text{img}}\) = 空间维度,\(S\) = 序列长度(时间步数),\(B\) = 批量大小。瓶颈列指出典型部署中限制性能的主要因素。对于 Transformer,\(\mathcal{O}(S^2)\) 内存项假设物化注意力分数;分块的精确注意力计算内核可以避免保留这一完整矩阵。
架构 参数量 前向传播 内存 并行化 瓶颈
MLP 每层 \(\mathcal{O}(d_{\text{in}} \times d_{\text{out}})\) 每层 \(\mathcal{O}(d_{\text{in}} \times d_{\text{out}})\) 权重 \(\mathcal{O}(d_{\text{in}}d_{\text{out}})\),激活值 \(\mathcal{O}(B d_{\text{out}})\) 极佳,矩阵操作可并行执行 内存带宽
CNN 每层 \(\mathcal{O}(k^2 \times c_{\text{in}} \times c_{\text{out}})\) \(\mathcal{O}(H_{\text{img}} \times W_{\text{img}} \times k^2 \times c_{\text{in}} \times c_{\text{out}})\) 特征 \(\mathcal{O}(H_{\text{img}} \times W_{\text{img}} \times c)\),权重 \(\mathcal{O}(k^2 \times c^2)\) 良好,空间位置相互独立 通常为计算吞吐量;逐通道卷积或小批量场景下为带宽
RNN 总计 \(\mathcal{O}(d_{\text{hidden}}^2+d_{\text{hidden}} \times d_{\text{in}})\) \(S\) 个时间步为 \(\mathcal{O}(S \times d_{\text{hidden}}^2)\) 循环状态为 \(\mathcal{O}(d_{\text{hidden}})\)(推理);激活值为 \(\mathcal{O}(S d_{\text{hidden}})\)(训练) 较差,存在顺序依赖 顺序依赖
Transformer QKV/O 投影为 \(\mathcal{O}(d_{\text{model}}^2)\),另加 \(\mathcal{O}(d_{\text{model}}d_{\text{ff}})\) 的前馈层 每层 \(\mathcal{O}(S^2 \times d_{\text{model}} + S \times d_{\text{model}}^2)\) 注意力 \(\mathcal{O}(S^2)\),序列 \(\mathcal{O}(S \times d_{\text{model}})\) 极佳(各位置),受内存限制 内存 \((S^2)\)

内存访问原语决定了单个执行核心从其本地内存层次结构获取数据的效率。然而,大规模执行神经网络需要协调多个核心、片上缓存及独立加速器之间的数据流。

数据移动原语

数据移动原语描述了张量值在处理单元、存储体和加速器互连之间的扇出与扇入。ALU 运算与数据传输之间在物理能耗上的差距表明,通过互连移动数据通常比计算本身产生更高的延迟和能耗。

通信模式可归结为四种基本集体通信操作:广播、分散、收集和归约。Figure 13 对比了它们的通信拓扑。

\begin{tikzpicture}[line join=round,font=\sffamily,scale=0.8, every node/.append style={transform shape}]
\definecolor{Ballcol}{RGB}{172,245,164}
\colorlet{Ballcol}{gray!20}%brown!60!black!20}%magenta!20!magenta!20}%orange!30}%blue!30!cyan!80}
\tikzset{%
LineA/.style={line width=0.75pt,black,-latex},
ALine/.style={line width=0.75pt,black,latex-}
}

\tikzset{
  box/.pic={
    \pgfkeys{/box/.cd, #1}
\foreach \x in {1,...,\columns}{
    \foreach \y in {1,...,\rows}{
        %
        \node[draw=none, fill=\ffill, minimum width=\cellsize, inner sep=0pt,
                    minimum height=\cellheight, line width=\llinewidth] (cell-\x-\y\br) at (\x*\cellsize,-\y*\cellheight) {};
      }
     }
   }
 }

\pgfkeys{
  /box/.cd,
  cellsize/.store in=\cellsize,
  llinewidth/.store in=\llinewidth,
  cellheight/.store in=\cellheight,
  columns/.store in=\columns,
  br/.store in=\br,
  ffill/.store in=\ffill,
  rows/.store in=\rows,
  columns=1,
  rows=3,
  br=A,
  ffill=red,
  cellsize=2mm,
  cellheight=5mm,
  llinewidth=0pt
}
\def\radius{6mm}

\begin{scope}[scale=1, every node/.append style={transform shape},
local bounding box=B1,shift={($(0,0)+(0,0)$)}]
\foreach \x in {1,2,3,4}{
\pgfmathsetmacro{\xcord}{1.6*\x}
\coordinate (1B-\x) at (\xcord,0);
\filldraw[fill=Ballcol] (\xcord,0) circle (\radius);
\pic[shift={(-0.20,0.5)}] at (1B-\x) {box={columns=1,rows=1,br=A,ffill=red}};
}
\pgfmathsetmacro{\xcenter}{(1.6*1 + 1.6*4)/2} %
\coordinate (1CB) at (\xcenter,-2.5);
\filldraw[fill=Ballcol]  (1CB) circle (\radius);
\pic[shift={({-0.20,0.5})}] at (1CB) {box={columns=1,rows=1,br=A,ffill=red}};

\foreach \x in {1}{
  \foreach \y in {1,2,3,4}{
    \edef\from{\x CB}
    \edef\to{1B-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[LineA] (from) -- node[inner sep=0pt](L\x){}(to);
  }
}
\node[below=7mm of 1CB]{广播};
\end{scope}

\begin{scope}[scale=1, every node/.append style={transform shape},
local bounding box=B2,shift={($(0,0)+(11,0)$)}]

\foreach \x/\col in {1/red,2/yellow,3/green,4/myblue}{
\pgfmathsetmacro{\xcord}{1.6*\x}
\coordinate (2B-\x) at (\xcord,0);
\filldraw[fill=Ballcol]  (\xcord,0) circle (\radius);
\pic[shift={(-0.20,0.5)}] at (2B-\x) {box={columns=1,rows=1,br=A,ffill=\col}};
}
\pgfmathsetmacro{\xcenter}{(1.6*1 + 1.6*4)/2} % Sredina između prve i četvrte lopte
\coordinate (2CB) at (\xcenter,-2.5);
\filldraw[fill=Ballcol]  (2CB) circle (\radius);

\foreach \x/\col in {1/red,2/yellow,3/green,4/myblue}{
\pgfmathsetmacro{\xcord}{0.2*\x}
\pic[shift={({-0.70,0.5})}] at ($(2CB)+(\xcord,0)$) {box={columns=1,rows=1,br=A,ffill=\col}};
}

\foreach \x in {2}{
  \foreach \y in {1,2,3,4}{
    \edef\from{\x CB}
    \edef\to{2B-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[LineA] (from) -- node[inner sep=0pt](L\x){}(to);
  }
}
\node[below=7mm of 2CB]{散发};
\end{scope}
%%%%%
\begin{scope}[scale=1, every node/.append style={transform shape},
local bounding box=B3,shift={($(0,0)+(0,-4.75)$)}]

\foreach \x/\col in {1/red,2/yellow,3/green,4/myblue}{
\pgfmathsetmacro{\xcord}{1.6*\x}
\coordinate (3B-\x) at (\xcord,0);
\filldraw[fill=Ballcol]  (\xcord,0) circle (\radius);
\pic[shift={(-0.20,0.5)}] at (3B-\x) {box={columns=1,rows=1,br=A,ffill=\col}};
}
\pgfmathsetmacro{\xcenter}{(1.6*1 + 1.6*4)/2} % Sredina između prve i četvrte lopte
\coordinate (3CB) at (\xcenter,-2.5);
\filldraw[fill=Ballcol]  (3CB) circle (\radius);

\foreach \x/\col in {1/myred,2/yellow,3/green,4/myblue}{
\pgfmathsetmacro{\xcord}{0.2*\x}
\pic[shift={({-0.70,0.5})}] at ($(3CB)+(\xcord,0)$) {box={columns=1,rows=1,br=A,ffill=\col}};
}

\foreach \x in {3}{
  \foreach \y in {1,2,3,4}{
    \edef\from{\x CB}
    \edef\to{3B-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[ALine] (from) -- node[inner sep=0pt](L\x){}(to);
  }
}
\node[below=7mm of 3CB]{收集};
\end{scope}
%%%%%%%
\begin{scope}[scale=1, every node/.append style={transform shape},
local bounding box=B4,shift={($(0,0)+(11,-4.75)$)}]

\foreach \x/\col in {1/1,2/3,3/5,4/7}{
\pgfmathsetmacro{\xcord}{1.6*\x}
\coordinate (4B-\x) at (\xcord,0);
\filldraw[fill=Ballcol]  (\xcord,0) circle (\radius);
%\pic[shift={(-0.20,0.5)}] at (4B-\x) {box={columns=1,rows=1,br=A,ffill=\col}};
\node[]at(4B-\x){\large\col};
}
\pgfmathsetmacro{\xcenter}{(1.6*1 + 1.6*4)/2}
\coordinate (4CB) at (\xcenter,-2.5);
\filldraw[fill=Ballcol]  (4CB) circle (\radius);
\node[]at(4CB){\large 16};

\foreach \x in {4}{
  \foreach \y in {1,2,3,4}{
    \edef\from{\x CB}
    \edef\to{4B-\y}
\path let
    \p1 = (\from),
    \p2 = (\to),
    \n1 = {atan2(\y2-\y1,\x2-\x1)}
  in
    coordinate (from) at ($ (\from) + (\n1:\radius) $)
    coordinate (to) at ($ (\to) + (\n1+180:\radius) $);
  \draw[ALine] (from) -- node[inner sep=0pt](L\x){}(to);
  }
}
\node[below=7mm of 4CB]{归约};
\end{scope}
\end{tikzpicture}
Figure 13: 数据移动原语:四种基本模式决定了神经网络计算中的信息流动。广播(左上)将单个值复制到所有目标位置,用于在批次内各元素之间共享权重。分散(右上)将不同元素分发到不同目标位置,从而实现工作划分。收集(左下)将分布在各处的值汇集到单个位置,例如注意力池化。归约(右下)通过聚合(求和、取最大值)合并多个值,常见于梯度同步和注意力评分。数据移动的能耗(参见“内存访问原语”一节)使这些模式成为关键优化目标。

广播操作将相同的数据从单一源分发到多个并行目的地。在批量 GEMM 执行中,驻留的权重分块被广播到多个处理器核心,每个核心计算一个独立的批次元素。加速器通过专用片上交叉开关或多播互连结构加速广播,而编译器则对循环进行分块,以最大限度地复用每个广播值。

散发操作将源张量划分为互不重叠的片段,并将不同切片发送到不同目的地。在空间划分或模型并行划分中,大型激活张量或权重张量被散发到各个计算分块或集群节点。在大语言模型中,MoE 架构引入了依赖输入的动态散发模式:门控网络将各个词元路由到分布在不同设备上的特定专家网络。由于词元路由取决于运行时输入,动态散发操作经常导致负载不均衡,使负载较轻的加速器闲置,而负载过重的专家则成为流水线瓶颈。

收集操作将分布式张量切片汇集到一个集中目的地。在稀疏推荐系统中,收集操作从分布式内存节点检索与稀疏特征索引对应的嵌入向量。在 Transformer 自注意力中,每个查询聚合所有序列位置的键值表示,因此收集沿序列维度进行。

归约操作使用求和或取最大值等满足结合律的算子,将多个输入值合并为一个聚合结果。归约广泛存在于神经网络中,包括计算层归一化、计算 softmax 归一化因子,以及在分布式数据并行工作进程之间同步权重梯度。加速器硬件通过专用树形归约网络和线程束级混洗寄存器加速归约,将完成延迟从 \(\mathcal{O}(n)\) 个串行步骤缩短为 \(\mathcal{O}(\log n)\) 个并行阶段。

在实际工作负载中,这些原语以复合阶段的形式执行。例如,对于序列长度为 \(S = 512\)、批大小为 \(B = 32\) 的单个 Transformer 注意力头,它会广播查询向量,沿序列维度收集键值对,并通过 softmax 分母对所得内积进行归约。当模型维度超出单个加速器的内存限制时,通过纵向扩展链路(如 NVLink 或 TPU 光互连网络)进行的集合通信决定了端到端吞吐量,使数据移动原语成为首要的架构约束。

对系统设计的影响

计算、内存访问和数据移动原语决定了物理芯片资源分配与编译器设计。只有当底层数学原语在代表性工作负载中占据主导地位时,硬件设计者才会将芯片面积分配给专用单元。

稠密矩阵乘法和卷积的广泛应用推动了专用矩阵引擎的发展,例如 Google TPU31 和 GPU Tensor Core。硬件加速 分析了这些执行单元如何将算法原语直接映射到芯片数据通路,以牺牲通用指令的灵活性来换取更高的稠密乘累加运算密度。

内存架构同样出现了分化,以适应不同的原语特征。为了同时支持可预测的流式访问以及随机或跨步访问,系统引入了高带宽内存(HBM),通过垂直堆叠 DRAM 裸片提供 2–3 TB/s 的带宽,比标准 DDR 通道高出一个数量级以上。在片上,加速器提供容量达数兆字节的 SRAM 层次结构,以及显式管理的暂存存储器,使编译器能够以可预测的方式控制工作集数据的暂存。

互连架构反映了数据移动原语的需求。为了支撑多加速器模型所需的大规模广播、收集和归约,现代平台集成了高带宽点对点链路,以及针对集合通信模式优化的专用片上网络路由器。

Table 13 总结了这种软硬件协同设计,将每种计算、内存和通信原语映射到相应的专用硬件加速、编译器优化和主要物理瓶颈。

Table 13: 原语与硬件协同设计:高效的机器学习系统需要将算法原语与底层硬件紧密集成。常见原语对应特定的硬件加速方式和软件优化方法,各自面临不同的实现挑战。Tensor Core 等专用硬件满足矩阵乘法和滑动窗口的计算需求,而批处理和动态图执行等软件技术则进一步提升性能。
原语 硬件影响 软件优化 关键挑战
矩阵乘法 Tensor Core 批处理、GEMM 库 并行化、精度
滑动窗口 专用数据通路 数据布局优化 步幅处理
动态计算 灵活路由 动态图执行 负载均衡
顺序访问 突发模式 DRAM 连续分配 访问延迟
随机访问 大容量缓存 内存感知调度 缓存未命中
广播 专用互连 算子融合 带宽
收集/散发 高带宽内存 工作分配 负载均衡

这些原语映射决定了系统能耗。如以下分析所示,跨越内存封装边界移动操作数所需的物理能耗,比算术运算能耗高出数个数量级。

两条采用对数刻度的水平能耗条,分别标注为 DRAM 640 pJ 和 FP32 乘法 3.7 pJ,其中 DRAM 条明显更长。

从 DRAM 移动一个 32 位数值所消耗的能量远高于一次 FP32 乘法。

MLP 中的大批量 GEMM 能够实现较高的算术强度,将权重加载成本分摊到多个输入上。相比之下,小批量 MLP 推理的复用程度极低,其大部分能量用于从片外 DRAM 移动权重。作为参考,一次 FP32 乘法的能耗约为 3.7 pJ/FLOP,而从 DRAM 读取单个 32 位操作数的能耗为 640 pJ (Horowitz 2014),两者的能耗相差 173×。虽然工作负载的总能耗取决于运算次数和复用因子,但低复用操作的能耗仍绝大部分由 DRAM 传输主导。这一物理现实促使加速器架构师配置大容量片上 SRAM,并采用晶圆级或多裸片封装,将活跃工作集保留在片上。

卷积操作通过在 \(H \times W\) 个空间位置上复用滤波器权重,降低每个输出的能耗。然而,实际能耗取决于实现细节。虽然 im2col 转换通过调用厂商 GEMM 库简化了执行,但对于步幅为 1 的滤波器,完整物化展开后的张量可能使临时内存流量最多增至原来的 \(K^2\) 倍。直接卷积算法和融合滑动窗口内核避免了这一中间缓冲区,从而显著降低内存流量和封装能耗。

RNN 中的顺序处理在各序列步骤之间体现出权重的时间复用。将紧凑的隐藏状态完全存储在片上 SRAM 中,可以消除循环激活值反复往返 DRAM 的开销。然而,严格的顺序依赖阻止了时间步之间的并行化,导致执行单元闲置,并增加每个词元的能耗。

在 Transformer 中,多头注意力引入了较高的数据移动开销。在标准的未融合实现中,物化完整的 \(S \times S\) 注意力矩阵会产生二次增长的内存读写次数(这一瓶颈详见 section 1.5.4)。FlashAttention 等分块实现将 softmax 计算融合到片上 SRAM 中,消除中间数据往返 DRAM 的开销,从而减轻这一负担,使注意力的能耗特征接近受计算限制的矩阵乘法。

在针对这些原语进行优化时,硬件架构师面临根本性的工程权衡。将芯片资源分配给宽而稠密的脉动阵列,可以最大限度地提高规则 GEMM 的吞吐量和能效,但在稀疏查找或动态路由期间,功能单元的利用率会偏低。反过来,扩大片上 SRAM 以容纳庞大的 Transformer 工作集,会增加裸片面积和静态漏电功耗,而稠密、规则的工作负载并不需要这些额外资源。

对计算原语进行剖析,可以确定各类架构的运行边界。在生产系统工程中,任务从分析单个算子转向在严格的运行约束下选择和配置完整架构,在预测准确率与 机器学习系统 中确立的平台预算以及 机器学习工作流 中的生命周期要求之间取得平衡。

架构选择框架

野生动物监测传感器必须在严格的毫瓦级功耗预算内对相机陷阱图像进行分类,而工业级推荐服务则必须在低于一毫秒的尾延迟预算内检索 TB 级嵌入。这些部署约束会立即排除那些在无约束预测基准上看似具有竞争力的架构。每类架构都体现了对数据结构和计算的不同物理假设:MLP 假设特征之间存在任意的两两交互,CNN 通过滑动窗口中的权重复用利用局部空间相关性,RNN 强制执行严格的顺序递归,而 Transformer 则在词元上下文中计算全互连注意力。架构选择是在优化内核或调整超参数之前,将这些计算拓扑与物理部署预算相匹配的系统性方法。

在数据—算法—机器分类体系中,架构选择定义了算法计算图(\(A\)),将输入数据不变量(\(D\))与物理执行硬件(\(M\))连接起来。这一边界上的结构性不匹配无法通过后续编译器优化或内核调优来弥补。选择框架从三个相互耦合的维度评估候选模型:输入数据的统计结构(\(D\))、模型的算法复杂度与算术强度(\(A\)),以及 机器学习系统 和 机器学习工作流 中确立的硬件执行边界,即内存容量、内存带宽、计算吞吐量和散热限额(\(M\))。同样的选择逻辑也适用于 数据选择 中的数据整理和 机器学习运维 中的集群部署。

数据到架构的映射

系统性的架构选择始于数据到架构的映射:使输入数据的结构对称性与不变量,同某类算子的计算和内存访问模式相匹配。section 1.1 中介绍的各类架构奠定了这一基础:MLP 适用于具有任意特征交互的表格记录,CNN 适用于具有局部空间相关性的网格结构数据,RNN 适用于具有时间递归关系的流式输入,Transformer 适用于词元之间存在任意两两依赖的关系上下文,而 DLRM 等稀疏嵌入架构适用于高基数类别型推荐数据流。

这种匹配反映了内存与计算之间的根本权衡。当一种架构将数据不变量直接编码到其计算算子中时,例如通过卷积权重复用实现平移等变性,就无需再从经验数据中学习这些对称性。与数据对称性相匹配的架构能够尽量减少参数数量,将中间激活值限制在片上 SRAM 内,并最大化算术强度。相反,部署缺乏适当归纳偏置的架构,会迫使模型通过超额配置参数来学习结构,成倍增加片外 DRAM 流量,并提高训练的样本复杂度。

在生产系统中,这些结构性权衡决定了工作负载如何在内存层次结构中划分:

  • MLP 处理稠密表格特征(如传感器遥测数据或精算表),其特征维度之间缺乏几何距离度量,所形成的矩阵向量运算具有确定性的延迟。
  • CNN 处理空间网格(如图像和频谱图),其中局部卷积核在整个特征图上复用滤波器权重,最大限度地提高寄存器和缓存复用。
  • RNN 处理时间状态有界的顺序数据流,在 SRAM 中维持紧凑的工作集,代价是逐步串行计算。
  • Transformer 通过动态全互连注意力处理词元序列和关系图 (Vaswani et al. 2017; Devlin et al. 2019; Wei et al. 2022),支持表达能力强的跨序列交互,同时带来二次增长的分数计算量和较高的激活内存流量。
  • 稀疏嵌入架构(DLRM) 将受内存容量限制的嵌入表与受计算限制的多层感知机解耦,在进行稠密特征交互之前,将数十亿个稀疏类别 ID 路由到大容量 DRAM 中。
Vaswani, Ashish, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, and Illia Polosukhin. 2017. “Attention Is All You Need.” Advances in Neural Information Processing Systems (NeurIPS) 30: 5998–6008.
Devlin, Jacob, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. 2019. “BERT: Pre-Training of Deep Bidirectional Transformers for Language Understanding.” Proceedings of the 2019 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, 4171–86. https://doi.org/10.18653/v1/n19-1423.
Wei, Jason, Xuezhi Wang, Dale Schuurmans, Maarten Bosma, Brian Ichter, Fei Xia, Ed H. Chi, Quoc V. Le, and Denny Zhou. 2022. “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.” Advances in Neural Information Processing Systems (NeurIPS) 35: 24824–37. https://doi.org/10.52202/068431-1800.

计算复杂度考量

数据与架构的匹配确立了功能适配性,但硬件约束下的渐近扩展行为决定了物理可行性。如果一种架构的计算需求或内存工作集增长超出了物理加速器的限制,就会违反延迟服务级别协议(SLA)或超出设备内存容量。

如 table 11 和 table 12 所归纳,每类架构在算术强度、工作集扩展行为和内存访问局部性方面都具有特定特征。评估这些特征可以识别制约生产部署的主要硬件瓶颈:内存带宽、算术吞吐量或顺序执行延迟。

可扩展性与生产环境考量

生产部署依据严格的服务级别协议评估架构,指标包括尾延迟、内存容量、每次查询的能耗和检查点恢复开销。这些运行指标是结构设计的直接物理结果,涉及稠密连接、空间局部性、顺序依赖或全互连注意力。决定表示能力的结构选择,也同时决定了执行并行度、缓存驻留情况和内存带宽消耗。

MLP 和 CNN 处于较简单的运行状态,因为推理在不同输入样本之间是无状态的,因此可通过数据并行实现吞吐量的线性扩展。然而,两者的内存访问特征存在显著差异。当批大小为 \(B=1\) 时,MLP 推理完全受内存带宽限制:从片外 DRAM 流式读取大型权重矩阵以计算单次矩阵—向量乘积,其算术强度接近 1 FLOP/字节,但延迟仍具有高度确定性。相比之下,CNN 执行能够在空间维度上实现较高的权重复用率,但中间激活的内存占用随图像分辨率(\(H_{\text{img}} \times W_{\text{img}} \times c\))增长,在高分辨率推理和训练反向传播过程中主导 SRAM 和 DRAM 的峰值容量需求。

RNN 和 Transformer 因不同的物理原因而面临具有挑战性的运行状态。RNN 维护紧凑的循环隐藏状态,但递推关系 \(h_t = f(h_{t-1}, x_t)\) 使执行沿时间维度串行化。根据阿姆达尔定律,增加并行执行单元无法降低这一关键路径上的延迟;此外,有状态执行也使分布式检查点保存和流水线恢复更加复杂。相比之下,Transformer 消除了顺序递推,在整个序列维度上并行执行词元投影,从而使脉动阵列和 Tensor Core 达到饱和。然而,标准自注意力的内存占用和计算量随序列长度 \(S\) 呈二次增长(section 1.5.4),其中,显式生成并存储 \(S \times S\) 注意力矩阵会迅速耗尽 HBM,并限制模型服务的最大批大小。较小的服务批次无法充分利用矩阵执行单元,而较大的批次则需要在多个设备之间划分内存。模型训练 通过数据并行、张量并行、流水线并行和序列并行,对这些分布式执行策略进行了形式化阐述。

硬件映射与优化策略

硬件映射将算子的代数结构与物理执行数据通路相匹配。MLP 中的稠密矩阵运算可直接映射到脉动阵列和 GPU Tensor Core(硬件加速 详细介绍了这些硅芯片实现)。这些工作负载受益于三类硬件级优化:分层矩阵分块(例如,面向 L1 缓存的 \(64{\times}64\) 分块、面向 L2 缓存的 \(256{\times}256\) 分块,以及 \(16{\times}16\) 的 Tensor Core 微分块),以确保数据驻留在寄存器和缓存中;混合精度执行(例如,采用 FP16 或 BF16 算术运算并以 FP32 累加),以使算术吞吐量翻倍并将内存流量减半;以及算子融合,将逐元素激活和偏置加法完全在寄存器文件内执行,从而消除中间数据与 DRAM 之间的往返传输。机器学习框架 探讨了编译器如何针对特定加速器生成这些融合内核的启动操作。

CNN 受益于专门的卷积算法和数据布局优化,这些方法与稠密矩阵运算的优化显著不同。Im2col 变换将卷积转换为矩阵乘法,但可能使临时存储和内存流量成倍增加;对于远离边界、步长为 1 且完全显式展开的 \(K{\times}K\) 滤波器,增幅可达 \(K^2\) 倍。Winograd 算法32可将 \(3{\times}3\) 卷积的乘法次数降至原来的 1/2.25×,但可能放大数值误差。采用定制内核的直接卷积可以避免 im2col 的显式展开,但需要针对具体架构进行调优。

由于增加计算硬件无法缩短顺序循环依赖(section 1.4.4),优化策略主要着眼于尽可能降低关键路径上的执行开销。循环展开通过增加指令缓存压力和激活存储开销,消除分支指令及每个时间步的控制开销。状态向量化将多个独立序列组成批次,分布到 SIMD 向量通道上,在不降低单序列延迟的情况下,将内存访问成本分摊到多个序列。波前并行化使双向模型中相互独立的前向传播与反向传播重叠执行,在模型拓扑允许的情况下提高执行单元的饱和程度。这些技术能够摊薄运行时开销,但无法改变根本的串行化约束。

自注意力需要通过内存层次结构优化,缓解二次增长的中间状态开销。由于计算和存储原始注意力矩阵会造成内存带宽瓶颈,主要的优化策略是在高速片上 SRAM 内对计算进行分块。FlashAttention:I/O 感知的注意力优化 将 FlashAttention33作为一种 IO 感知分块技术加以探讨,而结构化稀疏注意力则通过将注意力限制在固定的感受模式内来降低算术复杂度。

这些硬件权衡界定了各类架构的运行边界:MLP 为非空间特征向量提供确定性的低延迟执行;CNN 最大限度地复用空间网格中的数据;RNN 为流式序列维持极小的状态内存占用;Transformer 则以二次增长的内存带宽需求换取关系表达能力。要将这些硬件不变量转化为生产部署方案,需要一套结构化的决策流程。

决策框架

工程团队经常根据流行程度而非物理约束来默认选择架构——在线性模型或轻量级 CNN 已足够的场景中部署参数过多的 Transformer,或者选择超出推理延迟预算的模型。系统化选择以数据—算法—机器分类体系为基础,用有序的约束满足流程替代启发式判断。

figure 14 中的决策流程图首先识别输入数据特征,据此选择候选稠密架构(Transformer、RNN、CNN 或 MLP),然后依据物理硬件限制评估每个候选架构。高基数推荐工作负载不属于该稠密架构流程图的范围,应先转向稀疏嵌入/DLRM 架构族(section 1.7),再执行相同的内存、计算、速度、精度和部署检查。如果任何约束未得到满足,决策路径就会回退,缩减模型容量或更换架构族。

\scalebox{1}{%
\begin{tikzpicture}[font=\small\sffamily]
\tikzset{%
Line/.style={line width=1.0pt,black!50,text=black},
LineA/.style={BrownLine!80, line width=1.0pt,{-{Triangle[width=0.7*6pt,length=1.40*6pt]}},text=black},
  Box/.style={inner xsep=2pt,
    node distance=7mm,
    draw=GreenLine, line width=0.75pt,
    fill=GreenL,
    text width=35mm,align=flush center,
    minimum width=35mm, minimum height=10mm
  },
    Box1/.style={Box, draw=RedLine, fill=RedL, node distance=30mm},
    Box2/.style={Box, draw=BlueLine, fill=BlueL!50, node distance=10mm,
    },
    RedT/.style={blue!55!black,font=\footnotesize\sffamily},
 decision/.style = {align=flush center,text width=42mm,minimum width=40mm,diamond, aspect=2.2, node distance=6mm,
                             inner xsep=-3pt,  inner ysep=-2.95ex,fill=VioletL2, draw=VioletLine},
}
\node[Box2](B1){Transformer:注意力机制};
\node[Box2,right=of B1](B2){RNN:时间依赖};
\node[Box2,right=of B2](B3){CNN:局部特征检测};
\node[Box2,right=of B3](B4){MLP:稠密连接};
%start
\node[decision,node distance=15mm,above=of $(B2.north east)!0.5!(B3.north west)$](D1){何种\\ 数据类型?};
\node[Box,above=of D1](B0){开始:\\ 定义问题};
%below
\node[Box,node distance=10mm,below=of $(B2.south east)!0.5!(B3.south west)$](D2){检查\\ 约束};
\node[decision,below=of D2](D3){内存\\ 预算?};
\node[decision,below=of D3](D4){计算\\ 预算?};
\node[decision,below=of D4](D5){推理\\ 速度?};
\node[decision,below=of D5](D6){精度\\ 目标?};
\node[decision,below=of D6](D7){是否具备\\部署条件?};
%End
\node[Box,below=of D7](AS){架构\\ 已选定};
\node[Box1,right=of D7](SD){缩减模型规模或更换架构};
\node[Box1,left=2.5 of D6](IM){增加模型容量或更换架构};
%arrows
\draw[LineA](B0)--(D1);
\draw[LineA](D1.south)--++(0,-3mm)-|node[right,align=left,pos=0.77]{文本、复杂\\ 关系}(B1);
\draw[LineA](D1.south)--++(0,-3mm)-|node[right,align=left,pos=0.75]{时间序列、\\ 序列}(B2);
\draw[LineA](D1.south)--++(0,-3mm)-|node[right,align=left,pos=0.75]{图像、空间\\ 模式}(B3);
\draw[LineA](D1.south)--++(0,-3mm)-|node[right,align=left,pos=0.75]{表格、特征\\ 无关联}(B4);
\foreach \a in{1,2,3,4}{
\draw[LineA](B\a.south)--++(0,-4mm)-|(D2);
}
\draw[LineA](D2)--(D3);
\draw[LineA](D3)--node[right]{是}node[left,RedT]{充足}(D4);
\draw[LineA](D4)--node[right]{是}node[left,RedT]{可接受}(D5);
\draw[LineA](D5)--node[right]{是}node[left,RedT]{足够快}(D6);
\draw[LineA](D6)--node[right]{是}node[left,RedT]{已达到}(D7);
\draw[LineA](D7)--node[right]{是}node[left,RedT]{硬件适用}(AS);
%
\draw[LineA](D7)--node[above,pos=0,anchor=south west]{否}node[below,RedT,pos=0,anchor=north west]{硬件问题}(SD);
\draw[LineA](D3)-|node[above,pos=0,anchor=south west]{否}node[below,RedT,pos=0,anchor=north west]{不足}(SD);
\draw[LineA](D4)-|node[above,pos=0,anchor=south west]{否}node[below,RedT,pos=0,anchor=north west]{过慢}(SD);
\draw[LineA](D5)-|node[above,pos=0,anchor=south west]{否}node[below,RedT,pos=0,anchor=north west]{过慢}(SD);
%
\draw[LineA](D6)--node[above,pos=0,anchor=south east]{否}node[below,RedT,pos=0,anchor=north east]{未达到}(IM);
%
\draw[LineA](SD.east)--++(14mm,0)|-node[above,RedT,pos=0.8,anchor=south east]{不足}(D1);
\draw[LineA](IM.west)--++(-10mm,0)|-(D1);
\end{tikzpicture}}
Figure 14: 架构选择决策框架:根据数据特征和部署约束选择稠密神经网络架构的系统化流程图。该流程首先识别数据类型(文本/序列/图像/表格),以选择初始候选架构(Transformer/RNN/CNN/MLP),然后迭代评估内存预算、计算成本、推理速度、精度目标和硬件兼容性。高基数推荐工作负载由“稀疏架构”一节中的稀疏嵌入架构族(DLRM)单独处理,然后重新进入相同的约束检查流程。

当约束要求缩减模型规模时,模型压缩 中的模型压缩技术提供了系统化方法,可在保持精度的同时降低内存占用、计算量和延迟。该框架按顺序执行三个阶段:

  1. 数据对称性识别(\(D\)):识别输入数据中的结构对称性和不变性。空间局部性对应 CNN 候选架构;时间序列结构对应 RNN;不受约束的跨词元依赖对应 Transformer;不具有空间几何结构的表格特征对应 MLP;高基数类别 ID 对应稀疏嵌入表。
  2. 渐进式物理约束筛选(\(A \times M\)):依据硬件预算筛选候选模型:闪存/DRAM 中的静态参数存储、SRAM/HBM 中的动态激活峰值占用、相对于硬件 Roofline 上限的算术强度,以及尾延迟时限。若违反约束,则需要缩减模型宽度或深度、应用量化和压缩(模型压缩),或切换到开销更低的架构族。
  3. 容量与部署的实证验证:验证候选模型的容量能否在具有代表性的评估分布上达到目标精度。如果预测精度不足,则扩大模型容量并重新评估物理硬件约束。如果目标加速器硬件无法持续提供所需的算术吞吐量或内存带宽,则应选择其他架构,而非依赖小幅超参数调整。

归纳偏置层级

该决策框架沿着结构约束的连续谱运作,即 section 1.1 中引入的归纳偏置层级。在机器学习理论中,归纳偏置涵盖模型为泛化到已观测训练样本之外而采用的假设。在系统工程中,归纳偏置是提升效率的主要手段:约束假设空间能够限制参数量、限定中间激活工作集的规模,并向内存层次结构显露结构化的数据复用模式。

各架构族构成了结构约束逐渐减弱的层级:

  • CNN 通过局部连接、权重共享和平移等变性,体现出最强的架构偏置。这些约束大幅压缩参数量,并支持在寄存器和缓存中进行积极的分块暂存,但也将模型限制于网格结构输入。
  • RNN 通过时间递推和共享状态转移矩阵施加中等程度的结构偏置,使任意序列长度下的运行时内存占用保持有界,代价是执行串行化。
  • Transformer 体现出自适应归纳偏置,以所有词元对之间动态的、基于内容的注意力,替代固定的空间或时间拓扑。这种架构灵活性支持跨多种数据模态的泛化,但也将计算负担转移到规模呈二次增长的注意力矩阵和高内存带宽占用上。
  • MLP 的归纳偏置最小,不假设输入特征之间存在拓扑关系。在缺乏结构约束的情况下,学习空间或时间模式需要配置远超必要规模的参数并使用过量训练数据,导致算术强度和缓存局部性较差。

许多深度架构都实现了层次化表示学习,但使用的算子机制各不相同:CNN 通过逐步扩大感受野(section 1.3),RNN 通过隐藏状态演化(section 1.4),Transformer 则通过多头注意力(section 1.5)。这种层次化组织体现了一项基本物理原理:复杂表示由更简单的基本单元组合而成。在系统工程中,这种组合直接决定运行时效率。特征聚合流水线必须在组合基本单元时避免触发与片外 DRAM 之间的冗余往返传输。内存暂存必须与表示层级相匹配,以最大限度地复用片上 SRAM。此外,并行内核调度必须遵循各层之间的层次依赖关系,使执行单元在前向传播和反向传播过程中持续保持饱和。

实践中的架构选择

实时野生动物监测部署展示了数据结构、模型容量与物理硬件预算之间的相互作用。在确定采用某个候选架构之前,应通过吞吐量上限计算,判断目标硬件能否持续达到所需的帧处理速率。

Napkin Math 1.3: 吞吐量上限
问题:某实时应用必须使用 ResNet-50,以 30 FPS 的帧率处理视频。需要多大的持续计算吞吐量?

计算:

  1. 模型成本:ResNet-50 处理每张 \(224{\times}224\) 图像约需 8.2 GFLOP。
  2. 帧率:要求达到 30 FPS。
  3. 持续吞吐量:30 FPS \(\times\) 8.2 GFLOP = 246 GFLOP/s。
  4. 有效吞吐量:峰值 10 TFLOP/s \(\times\) 50–60% 的利用率 = 5 TFLOP/s–6 TFLOP/s。
  5. ResNet-50 算力余量:5 TFLOP/s \(\div\) 246 GFLOP/s = 20.3×。
  6. 检测模型检查:30 FPS \(\times\) 100 GFLOP = 3 TFLOP/s,按有效吞吐量的较低估计值计算,仍有 1.7× 的算力余量。

系统洞见:在此规划场景中,理论峰值性能为 10 TFLOP/s 的中端 GPU 可达到约 50–60% 的利用率,有效性能为 5 TFLOP/s–6 TFLOP/s。对于以 30 FPS 运行的 ResNet-50,系统具有 20.3× 的性能余量。然而,切换到每帧计算量为 100 GFLOP 的目标检测模型后,需要 3 TFLOP/s 的持续性能,仅剩 1.7× 的性能余量。批大小约束或多流处理会迅速将系统推向计算上限。ResNet-50 受计算限制,但其余量取决于加速器以及实际达到的利用率。

吞吐量上限将抽象的计算需求转化为具体的硬件利用率百分比。实际部署还会引入仅凭该上限无法体现的物理约束。

实例分析:实时野生动物监测

设计任务是构建一个嵌入式机器学习系统,根据偏远国家公园内相机陷阱拍摄的图像对野生动物物种进行分类。部署系统必须在完全没有网络连接的条件下,全部在设备端执行推理,依靠太阳能充电电池运行六个月,并在 50 个目标动物物种上达到 90 percent 的准确率。选型过程由五个评估阶段指导:数据特征分析、部署约束剖析、候选架构评估、硬件预算验证以及运行风险评估。

输入数据由相机陷阱图像帧组成(传感器原始分辨率为 \(1920{\times}1080\),下采样至 \(224{\times}224\) 用于推理)。物种分类依赖的视觉特征具有三种不变性质:空间局部性(毛皮纹理或耳朵形状等判别性模式占据有界的像素邻域)、平移等变性(动物的身份不随其在画面中的空间位置变化而改变)以及层次组合性(底层边缘组合成纹理、解剖部位和完整生物体)。这些不变性质直接指向 CNN,其局部卷积核权重共享机制原生编码了这些几何对称性,避免了无约束 MLP 会产生的参数爆炸。

约束分析将部署环境转化为严格的硬件边界。Table 14 列出了这些物理约束及其各自施加的架构要求:

Table 14: 野生动物监测约束:五项部署约束及其对相机陷阱场景的影响。没有网络连接排除了仅在云端执行推理的方案,而功率、延迟、内存和准确率要求必须在目标设备上验证。
约束 要求 影响
连接性 无(离线) 所有推理必须在设备端运行
功率 平均约 2 W(太阳能 + 电池) 排除 GPU;必须使用低功耗 MCU 或边缘 NPU
延迟 每次检测 <500 ms 允许批大小为 1,无实时流式处理
内存与存储 512 MB RAM,2 GB 存储空间 模型、激活值和运行时缓冲区必须能容纳于本地
准确率 50 个物种上达到 90% 以上 需要足够的模型容量

确定物理约束后,依据参考模型基线评估候选架构:

  • ResNet-50(25.6M 个参数,8.2 GFLOP):计算开销和散热需求过高,无法适应 2 W 的功率限制。FP32 格式下为 102.4 MB,仅权重存储就耗尽了 100 MB 分配额度中的大部分,尚未计入激活缓冲区或操作系统开销。
  • MobileNetV1(4.2M 个参数,1138 MFLOP):算术强度和资源占用可行。以 INT8 存储权重可将模型占用降至 4.2 MB(FP32 下为 16.8 MB),而采用因式分解的深度可分离卷积可大幅减少算术运算。
  • KWS DS-CNN(200K 个参数,20 MFLOP):容量不足。其规模面向 12 类关键词检测,参数预算不足以区分 50 个视觉物种类别。

MobileNetV1 展示了深度可分离卷积的可行性,而 MobileNetV2 则通过带线性瓶颈的倒残差块,实现了更高的参数效率和更好的内存局部性。采用 0.75× 的宽度乘数配置模型,可得到约 2.6M 个参数(FP32 下为 10.4 MB,使用 INT8 权重时为 2.6 MB),在 \(224{\times}224\) 输入分辨率下的计算量约为 418 MFLOP。该模型能够轻松满足分配的内存预算,同时保留对 50 个目标物种的表征能力。

硬件验证依据物理平台预算检查所选模型。内存占用满足设备可用 RAM 的限制: \[ \text{$\underbrace{\text{2.6 MB}}_{\text{Model}} + \underbrace{224 \times 224 \times 64 \times 4 \approx \text{12.8 MB}}_{\text{Activations}} + \underbrace{\text{50 MB}}_{\text{OS/Buffers}} = \text{65.4 MB} \ll \text{512 MB}~\checkmark$} \]

计算预算在目标片上系统(SoC)上得到验证,该系统采用主频为 1.2 GHz、支持 NEON SIMD 的 ARM Cortex-A53(INT8 性能约为 2 GOPS): \(\frac{418 \times 10^6 \text{ INT8 ops}}{0.002 \times 10^{12} \text{ INT8 ops/s}} = 209 ms \text{ latency} \ll 500 ms \text{ target}~\checkmark\)

工作功率是最后一道物理约束。按工作状态下的推理功率约为 200 mW、持续时间为 209 ms 估算,每次分类消耗 41.8 mJ。对于 100 inferences/day 的触发式推理频率,模型执行每天消耗 4.2 J。这为图像传感器采集、休眠状态静态电流、非易失性存储日志记录以及外设管理留下了充足的电池能量余量。

第五步评估现场运行风险。Table 15 将主要的准确率、热管理和覆盖范围失效模式与相应的系统工程缓解措施配对列出:

Table 15: 野生动物相机部署风险:MobileNetV2 部署中的主要准确率、热管理和物种覆盖风险,以及为各项风险选定的工程缓解措施。
风险 缓解措施
未达到 90% 准确率 使用增强数据集训练;若 MobileNet 能力不足,则考虑 EfficientNet-Lite
机箱内发生热降频 增加被动散热器;在高温条件下降低推理频率
部署后新增物种 扩展或重新训练输出头,并规划空中下载(OTA)更新机制

最终部署方案确定采用量化为 INT8 的 MobileNetV2(宽度乘数为 0.75×),运行在配备 512 MB RAM 的 ARM Cortex-A53 SoC 上。该配置满足工作状态下的计算、内存占用和功率预算,每帧处理时间约为 209 ms,同时为系统软件保留了充足的内存余量。最终现场验收需要在目标相机数据分布上测量分类准确率,并验证季节性温度变化条件下的电池续航能力。

本案例将抽象的架构原则转化为具体的规模配置决策。然而,生产环境中的架构选型经常面临反直觉的权衡:FLOPs 更少的模型可能在带宽受限的硬件上停滞,表达能力强的架构可能在缺乏匹配结构的数据集上性能下降,而实验室原型可能因部署环境的内存层次结构而失效。将这些失效模式置于真实硬件条件下考察,便能揭示系统设计中的主要谬误与陷阱。

谬误与陷阱

架构选择是一项系统决策,而非排行榜选型。本节讨论的常见错误,源于团队将不同架构家族视为可互换的准确率工具,却忽视了归纳偏置、内存流量、硬件映射和部署状态。

谬误:更复杂的架构总是优于更简单的架构。

工程师往往认为,Transformer 在所有任务上都优于更简单的架构。在生产环境中,架构的复杂程度必须与问题复杂度相匹配:算法必须同时适应数据结构和机器成本。section 1.2.1 中的 MNIST 对比表明,示例 CNN 的参数量为示例 MLP 的 47× 分之一,因为其局部性偏置与图像结构相匹配。准确率、训练成本和推理延迟仍需针对具体实现和任务进行测量。

陷阱:仅依据准确率指标选择架构,而不分析计算需求。

实践者依据论文报告的总体准确率选择架构,却忽略了计算层面的影响。RNN 存在限制并行性的串行关键路径,而 Transformer 则面临二次复杂度的稠密注意力分数计算;在朴素实现中,分数存储也具有二次复杂度。因此,序列长度为 2,048 时,显式存储注意力分数所需的内存是长度为 512 时的 16×。忽视这些特性的系统可能无法达到延迟目标、超出内存预算,并且硬件利用率远低于预期。

谬误:一个架构在训练和推理过程中具有同一个主导瓶颈。

同一个计算图可能处于不同的系统运行区间。Transformer 训练和预填充会同时处理多个位置,可能受稠密注意力计算限制;小批量自回归解码则反复流式读取权重和 KV 缓存状态,可能受内存带宽限制。批处理、序列长度、精度和缓存布局都可能改变这一边界。因此,一个运行区间中的基准测试无法确定另一个运行区间的瓶颈;应依据机器学习系统铁律分别进行测量。

陷阱:组合架构模式时,不分析系统层面的交互效应。

工程师向 CNN 添加注意力,或向 Transformer 添加卷积,期望收益能够叠加。每种模式都会产生不同的内存访问特征:CNN 通过滑动窗口利用空间局部性,而稠密注意力会引入全对全的分数计算。将两者组合可能增加中间数据流量并破坏局部性,因此无法通过叠加各组件的收益来推断混合架构的吞吐量。同样,向 Transformer 添加循环连接会重新引入串行依赖。成功的混合架构需要在组合模式之前,剖析内存访问和缓存行为。

谬误:架构在训练硬件上取得的优势可以直接迁移到部署硬件上。

团队针对高端 GPU 集群进行设计,随后却发现模型无法在目标硬件上成功部署。利用 8\(\times\) A100 GPU(总内存为 640 GB)的架构,无法不经修改就部署到具有代表性的边缘节点上,例如 NVIDIA Jetson Orin NX(系统内存为 16 GB)。正如 section 1.10.3 所强调的,架构选择必须分析完整的系统栈,因为存储、延迟和功耗预算会随部署目标而变化。

陷阱:在估算 Transformer 模型服务成本时忽略 KV 缓存的增长。

团队仅根据模型权重占用的内存来制定 Transformer 部署预算,忽略了自回归生成过程中使用的键值(KV)缓存 (Pope et al. 2023; Kwon et al. 2023)。缓存规模按 \(\mathcal{O}(B \times N_L \times 2 \times N_{\text{heads}} \times S \times d_{\text{head}})\) 增长,其中,\(B\) 为并发序列数,\(N_L\) 为层数,因子 2 表示需要存储键和值,\(N_{\text{heads}}\) 为注意力头数,\(S\) 为序列长度,\(d_{\text{head}}\) 为注意力头维度。在长上下文或高并发条件下,这项开销可能成为限制模型服务的关键约束。Section 1.6.4.2 逐步分析了本章中具有 32 层、32 个注意力头的示例。当注意力头维度为 128、序列长度为 2,048 个词元,并采用 FP16 存储时,每个并发请求持有的 KV 缓存约为 \(\approx\) 1 GB。在 2–4 个用户并发时,仅缓存就占用 2 GB–4 GB,这尚未计入分配器、激活值和工作区的开销。这些数值不会耗尽内存容量为 80 GB 的设备,但会占用加载权重后剩余内存的一部分,并随上下文长度和并发量线性增长。因此,容量规划必须将权重、缓存和运行时缓冲区纳入统一预算;当合计占用接近设备内存容量时,应降低并发量、缩短上下文、减少缓存占用,或增加内存容量。

Pope, Reiner, Sholto Douglas, Aakanksha Chowdhery, Jacob Devlin, James Bradbury, Jonathan Heek, Kefan Xiao, Shivani Agrawal, and Jeff Dean. 2023. “Efficiently Scaling Transformer Inference.” Proceedings of Machine Learning and Systems (MLSys) 5: 606–24.

总结

架构即基础设施。 在 MLP、CNN、RNN、Transformer 和推荐模型(DLRM)之间进行选择,就确定了机器学习系统铁律串行形式(\(T_{\text{exec}} = D_{\text{vol}}/\text{BW} + O / (R_{\text{peak}} \cdot \eta_{\text{hw}}) + L_{\text{lat}}\))中的物理项。从模式处理需求、算法结构、计算映射和系统影响这四个方面审视每种架构,可以发现,架构的数学归纳偏置在很大程度上决定了铁律中的哪一项会制约硬件性能。

本章开篇介绍的架构家族和五个灯塔模型,直接对应于这些物理界限。ResNet-50 对权重的空间复用提高了算术强度(\(I = O/D_{\text{vol}}\)),使执行进入计算受限区域(\(O/R_{\text{peak}}\))。小批量自回归 GPT-2 生成的算术强度较低,执行受限于内存带宽(\(D_{\text{vol}}/\text{BW}\))。RNN 的时间递归引入了无法并行化的串行关键路径,抬高了延迟下限(\(L_{\text{lat}}\))。DLRM 的稀疏嵌入会撞上铁律之外的容量墙:在任一执行项成为首要可行性检验之前,其嵌入表就可能超出加速器内存容量。MobileNetV2 和 KWS 则说明,如果算子的形状无法使硬件功能单元达到饱和,较低的 FLOP 数也无法保证吞吐量。

要点回顾: 架构即基础设施
  • 归纳偏置是贯穿始终的概念:每种架构都编码了结构性假设,例如 CNN 的局部性、RNN 的序列性以及 Transformer 的全局上下文。这些偏置以通用性换取样本效率,并决定架构能够高效解决哪些问题。
  • 算术强度有助于识别瓶颈:将工作负载的算术强度与目标硬件在 Roofline 模型中的平衡点进行比较,有助于判断计算能力还是内存带宽更可能构成制约。
  • 二次方成本是持续存在的约束:稠密 Transformer 注意力需要计算 \(\mathcal{O}(S^2)\) 个得分交互。朴素实现还需要二次方规模的得分存储;分块精确注意力消除了这项存储成本,但没有消除稠密计算。
  • 灯塔模型揭示不同的瓶颈:ResNet-50(计算)、GPT-2(带宽)、DLRM(容量)、MobileNetV2(延迟)、KWS(功耗)。这些典型模型有助于诊断给定系统由哪种物理约束主导。
  • 深度受益于架构支持:跳跃连接和归一化能够改善极深网络的优化,但并非超过某个固定深度后就普遍必需的条件。这些诞生于 CNN 的构建模块可以迁移到许多深度架构中,包括 Transformer。
  • FLOP 数不等于速度:ResNet-50 与 MobileNetV2 的 FLOP 数之比为 13.7×,但当 MobileNetV2 的算子形状和算术强度无法充分利用可用计算单元时,它在某些数据中心 GPU 上的运行速度反而可能更慢。吞吐量取决于架构与硬件的匹配程度,而不仅仅是运算次数。
  • 选择架构就是选择部署方式:选择 Transformer 而非 CNN,会决定内存需求、延迟下限、硬件利用率和基础设施成本。架构本身就是系统约束。

归纳偏置与系统成本是同一选择的两个视角。局部性、递归或不受限制的词元交互等假设,有助于模型从有限样本中泛化,同时也决定了中间数据的形状、复用方式和生命周期。因此,在框架选择内核之前,算法选择就已经转化为对内存容量、带宽和调度的要求。

选择架构,就是与硬件签订一份物理契约。CNN 承诺遵循空间局部性并复用权重;稠密注意力承诺执行 \(\mathcal{O}(S^2)\) 的得分计算;RNN 则承诺遵循串行的时间步依赖。这些拓扑选择确定了基本工作负载项 \(O\)、\(D_{\text{vol}}\) 和 \(L_{\text{lat}}\),进而支配内存占用、带宽需求和并行效率。运行时技术可以提高履行契约的效率,却无法消除契约本身:分块精确注意力消除了中间得分的存储,却没有改变二次方级别的算术运算下限;流水线并行则划分了递归计算任务,却没有消除串行时间步路径。因此,系统工程师可以在实现之前,将模型的归纳偏置和数据几何结构与芯片的物理特性相匹配,从而预判可能发生的瓶颈转移。

后续内容: 从蓝图到构建
基础计算原语(神经计算)在本章中转化为具体的架构契约。将抽象蓝图转化为可执行的运行时,需要在数学图与物理硬件之间建立桥梁。架构确定必须执行什么工作;机器学习框架决定如何调度和分派这些工作。机器学习框架 探讨 PyTorch、TensorFlow 和 JAX 如何将高层架构图转换为计算有向无环图(DAG)、自动微分图,以及直接在芯片上执行的优化设备内核。

Back to top

Footnotes

  1. 归纳偏置:源自拉丁语 inducere,意为“引入”。编码一种结构假设,会将模型“引导”至更小的解空间,因此这一概念贯穿整章:本章讨论的每种架构——多层感知机(MLP)、卷积神经网络(CNN)、循环神经网络(RNN)和 Transformer——都由其偏置选择所定义。与等效的 MLP 相比,CNN 的局部性偏置可使参数数量降低数个数量级,直接缩减铁律中的 \(O\) 和 \(D_{\text{vol}}\) 项,而全局注意力则以二次规模的分数计算换取长程连接。↩︎

  2. 自回归生成:一种解码策略,其中每个输出词元都以此前生成的所有词元为条件,每生成一个词元都需要执行一次完整的模型前向传播;对于参数量为 1.5B、采用 FP16 的模型,此处使用的仅考虑权重、批大小为 1 的模型在每个解码步骤中读取约 3 GB 的权重,得到的计算量与字节数之比约为 1 FLOP/byte。这种较低的算术强度通常使批大小为 1 和小批量解码受带宽限制;较大的批量可以摊薄权重传输开销。在生成过程中,模型服务系统还会保留先前词元的注意力状态;section 1.5 将这种状态称为 KV 缓存。↩︎

  3. 感知机:英文名称 Perceptron 由“perception”(感知)和表示装置的后缀“-tron”(如 cyclotron,回旋加速器,以及 klystron,速调管)组合而成,由弗兰克·罗森布拉特 (Rosenblatt 1957) 创造,用于命名神经计算的基本单元:先求加权和,再执行非线性激活,这是对早期 McCulloch-Pitts 神经元的扩展。MLP 完全由这些单元按全连接层组织而成,因此这一单一操作,即乘加运算的效率决定了系统吞吐量。现代加速器每秒执行超过 \(10^{14}\) 次此类操作,使感知机成为整个机器学习硬件生态系统围绕其进行优化的计算原语。↩︎

  4. 通用逼近定理(UAT):该定理通过证明足够宽的网络能够逼近任意连续函数,为 MLP 的“无先验结构”归纳偏置提供了数学保证。系统层面的难点在于,“足够宽”可能要求神经元数量随输入维度呈指数增长,使得即便对于 \(256{\times}256\) 图像这样规模适中的输入,这一理论保证在实践中也难以实现。↩︎

  5. 流形假设:假定高维数据位于嵌入完整空间的低维曲面上;一幅 \(256{\times}256\) 图像位于一个 65,536 维空间中,但“有效的猫图像”仅占据其中一个很小的结构化区域。深度网络逐步将这一折叠的流形展开为线性可分的表示。其系统层面的意义是:如果数据确实占据整个空间,那么任何架构都无法从规模可行的数据集中学习;正是流形结构使有限的训练预算足以支持学习。 ↩︎

  6. 没有免费午餐定理:Wolpert 和 Macready 在 1997 年的研究结果证明,没有任何优化算法能在所有可能的问题上都优于随机搜索:对所有可设想的函数取平均后,所有算法都是等价的。其对机器学习系统的意义在于,归纳偏置(局部性、等变性、注意力)能够改善与该偏置相匹配的问题上的表现,却可能在其假设不成立时损害表现,因此,选择架构意味着在工程上针对某类问题作出承诺。↩︎

  7. MAC(乘加):神经网络的原子操作:将两个值相乘,并将结果加到累加和中。在 Horowitz 的 45 nm 参考数据中,一次 FP32 乘法加一次加法的能耗约为 4.6 pJ,而一次 32 位片外 DRAM 访问的能耗约为 640 pJ (Horowitz 2014)。这些与工艺技术相关的数值说明了为什么数据移动的能耗可能超过算术运算;它们并非适用于当前硬件的通用常数。 ↩︎

  8. BLAS(基本线性代数子程序):这一矩阵运算标准 API 支持使用高度优化的库(例如 cuBLAS)来加速每个神经元的 784 次乘加运算。MNIST 示例中的 \(784{\times}100\) 矩阵对硬件的利用效率可能低于规模更大、对齐良好的 Transformer 矩阵,因为利用率取决于矩阵形状、批处理、数据类型、库和加速器。↩︎

  9. Tensor Core:NVIDIA GPU 中的专用单元,通过将上述数千次乘加操作融合为单条高度并行的矩阵指令来实现加速。当矩阵维度满足特定数据类型和架构所要求的对齐倍数时,Tensor Core 的效率最高;现代 cuBLAS/cuDNN 在许多未对齐的情况下仍可使用 Tensor Core,但通常效率较低,或需要内部填充。这一架构层面的启示不依赖于厂商:专用矩阵单元适合稠密、对齐的通用矩阵乘法(GEMM)工作负载,而对于无法充分占用这些单元的小型、不规则形状,其效率会降低。 ↩︎

  10. 卷积:源自拉丁语 convolvere(“卷在一起”),描述滤波器在输入上滑动,并在每个位置组合局部元素的过程。这种“卷在一起”的方式施加了局部性约束,而这正是该运算高效的根源:一个 \(5{\times}5\) 卷积核在每个空间位置复用其 25 个权重,使针对一幅 100 万像素单通道图像的单个特征检测器所需的权重数从约 1,000,000 个减少到 25 个,参数量约为全连接检测器的四万分之一,即减少约 40,000\(\times\)。 ↩︎

  11. ImageNet:这一数据集大规模验证了上述两项空间处理要求。AlexNet 在 2012 年 ImageNet 大规模视觉识别挑战赛中获胜,在包含约 120 万张训练图像、1000 个类别的挑战任务上,将 top-5 错误率从 26.2% 降至 15.3% (Krizhevsky et al. 2012);最初发布的 ImageNet 包含 320 万张图像,覆盖 5,247 个同义词集 (Deng et al. 2009)。后续架构通过调整架构、优化方法、数据和计算预算来提高准确率,体现了归纳偏置与基础设施成本之间的相互作用。 ↩︎

  12. 平移等变性:卷积运算的固有性质,即输入发生平移时,所生成的特征图必然发生相应的空间平移。这不同于不变性;池化或后续聚合可以通过丢弃精确位置信息来近似实现不变性。例如,步幅为 2 的 \(2{\times}2\) 池化可使空间元素数量减少 75%。↩︎

  13. Yann LeCun 与 LeNet:LeCun 的架构通过强制采用局部连接和参数共享原则,直接解决了将稠密网络应用于图像时难以控制的规模扩张问题。这些约束使类图像输入层的参数量减少了 95% 以上,使 LeNet-5 仅用约 60,000 个总参数,就能在支票识读等商业任务中达到生产级准确率。 ↩︎

  14. 感受野:影响某个特定输出神经元的输入区域。使用 \(3{\times}3\) 滤波器时,感受野的边长每层增加 2 个像素,因此第 3 层的神经元能够“看到”一个 \(7{\times}7\) 区域。这一增长速率约束了架构深度:要在 \(224{\times}224\) 图像中检测跨度超过 100 个像素的对象,需要深度堆叠小滤波器(层数更多,存储激活值所需的内存更多),或采用更大的卷积核(每层参数更多),这是 CNN 设计中深度与宽度之间的一项基本权衡。 ↩︎

  15. SIMD(单指令多数据):同时对多个数据元素执行相同操作的 CPU 指令;AVX-512 每条向量指令可处理 16 个单精度数值;相较于标量代码的实际加速效果还取决于指令吞吐量、向量化程度和内存访问。对于无法使用 GPU 的边缘 CPU 上的 CNN 推理,SIMD 利用率可能影响模型能否达到实时延迟目标。TFLite 和开放神经网络交换(ONNX)Runtime 等框架通过向量化卷积内核利用这种并行性。 ↩︎

  16. Bahdanau 注意力:该方法允许解码器在每个输出步骤动态查询所有输入元素,从而突破了此前序列到序列模型的“定长向量”瓶颈,并形成了上述自适应连接。它以学习得到的、基于内容的加权系统,取代了固定容量通道的结构约束。其核心权衡是接受线性的 \(\mathcal{O}(S)\) 内存开销来存储所有输入状态,以克服单个向量固有的信息丢失问题。↩︎

  17. Transformer:其奠基论文《注意力就是你所需要的一切》明确提出了一个系统层面的主张:并行注意力机制可以完全取代顺序循环处理。这种架构权衡消除了 RNN 的 \(\mathcal{O}(S)\) 路径长度对并行性的约束,但引入了 \(\mathcal{O}(S^2)\) 的稠密分数计算;朴素实现还会物化 \(\mathcal{O}(S^2)\) 的分数存储。这种二次复杂度的计算持续影响着上下文窗口的工程设计。↩︎

  18. 查询—键—值(QKV):这些术语借自信息检索,说明了该公式为何使用三种不同的学习投影来计算成对分数。构建这些投影需要三个独立的权重矩阵,每层耗费 \(3 \times d_{\text{model}}^2\) 个参数。其直接的系统后果是自回归推理中的“KV 缓存”:必须存储所有先前的键向量和值向量,以供下一个词元使用,这使内存占用随序列长度线性增长(\(\mathcal{O}(S)\)),并可能在长上下文或高并发时占据服务内存的主要部分。↩︎

  19. Softmax:其名称源于它是 argmax 的“软”(可微)版本,其数学根源可追溯至玻尔兹曼统计力学。softmax 对每个查询行的全部 \(S\) 个分数进行归一化;朴素注意力实现会在归一化之前物化完整的 \(S{\times}S\) 矩阵。相比之下,FlashAttention 所采用的在线 softmax 和分块技术会维护持续更新的归一化统计量,无需在 HBM 中保留完整矩阵即可计算精确注意力。因此,softmax 需要对每一行执行归约,但并不强制要求二次规模的辅助存储;稠密成对分数计算仍然具有二次复杂度。 ↩︎

  20. 注意力缩放 \((\sqrt{d_k})\):这种归一化直接抵消查询—键点积方差 \((d_k)\) 的线性增长,防止 softmax 函数进入原本会导致梯度消失的饱和区域。这在混合精度训练中对系统的影响最为显著:当激活值变大时,未经缩放的点积可能产生超出 16 位浮点数范围的 logits,导致学习过程不稳定,甚至完全停止。↩︎

  21. KV 缓存的内存规模增长:对于采用 FP16 的 70 亿参数 Transformer,模型权重占用约 14 GB;单个请求的缓存需要 32 层 \(\times\) 2 (K,V) \(\times\) 32 个头 \(\times\) 2,048 个位置 \(\times\) 128 维 \(\times\) 2 字节,即约 1.07 GB。在 8 个用户并发时,缓存约为 8.6 GB,在权重之外增加了可观的内存占用。由于缓存随上下文长度和并发数线性增长,提高吞吐量迫使系统在分组查询注意力 (Ainslie et al. 2023)、更短的上下文,或 KV 分页与卸载 (Kwon et al. 2023) 等方案之间作出选择。分页和卸载保持模型输出不变,而分组查询注意力会改变架构,更短的上下文则会截断历史上下文。↩︎

  22. 嵌入:这一术语源于将一个空间嵌入另一个空间的数学概念。神经嵌入将离散词元(例如用户 ID 或词汇表中的单词)映射到连续向量空间,使几何邻近性能够表征语义相似性。Word2vec 于 2013 年推动了神经词嵌入的普及。对系统而言,嵌入表形成了一种独特的内存访问模式:每次查找都是对一张可能达到 TB 级规模的表的不规则读取,从而产生稀疏且受带宽限制的工作负载,使 DLRM 在根本上区别于 ResNet 等受计算限制的架构。↩︎

  23. 反向传播:Rumelhart、Hinton 和 Williams 于 1986 年展示了如何高效应用链式法则来训练多层网络;标准的反向模式训练会保留反向传播所需的前向激活,因此激活内存通常随网络深度增长。检查点、重计算和卸载可以通过增加计算或数据移动来减少存储的激活。因此,决定给定加速器上最大可行批大小的关键内存约束,可能是激活存储,而非权重存储。 ↩︎

  24. 批归一化(BatchNorm):最初提出的归一化层 (Ioffe and Szegedy 2015),使用每个小批量的统计量重新缩放激活。在一项 ImageNet 实验中,它以原来 1/14 的训练步数(即 14\(\times\) 的步数缩减)达到了目标准确率。其对批量大小的依赖,以及训练与服务偏差(推理时从批统计量切换为运行平均值),构成了促使替代方案出现的系统局限:LayerNorm 为 Transformer 消除了对批量的依赖,而 RMSNorm 则去除了均值中心化。↩︎

  25. RMSNorm(均方根归一化):由 Zhang and Sennrich (2019) 在 NeurIPS 上提出,RMSNorm 仅使用均方根进行归一化,省去均值中心化步骤,从而简化了 LayerNorm。在该论文测试的模型和实现中,相较于 LayerNorm,RMSNorm 将总体运行时间缩短了 7–64%。LLaMA 系列和 Mixtral 风格的 Transformer 报告采用了 RMSNorm (Touvron, Lavril, et al. 2023; Touvron, Martin, et al. 2023; Jiang et al. 2024),说明了为何一次归约遍历就可能对 Transformer 推理延迟产生重要影响。 ↩︎

  26. LSTM(长短期记忆):由 Hochreiter 和 Schmidhuber 于 1997 年发明,LSTM 引入了“恒定误差环”,这是一种带门控的单元状态,可在通过时间的反向传播过程中保护误差信号,使其免于指数衰减。该方案的系统成本在于:标准 LSTM 需要计算输入门、遗忘门和输出门,以及候选单元更新,因此每个时间步大约需要四次仿射变换,而普通 RNN 只需一次。这种计算开销解释了为何通过可并行化注意力解决长距离依赖的 Transformer,在许多大规模语言工作负载中取代了 LSTM。 ↩︎

  27. GRU(门控循环单元):Cho et al. (2014) 描述了一种用于编码器—解码器翻译的门控隐藏单元,它使用重置门和更新门来控制隐藏状态的更新方式。相较于 LSTM 的输入门、遗忘门和输出门以及候选单元更新,这种方式实现了更简单的门控循环。更广泛的系统启示是:在保持任务性能的前提下,简化架构可以减少状态和矩阵运算,这一原则在从 MobileNet 到蒸馏 Transformer 的各类效率导向设计中反复出现。 ↩︎

  28. 视觉 Transformer(ViT):Google 2020 年的 ViT 论文将 \(224{\times}224\) 图像切分为 \(16{\times}16\) 图像块(196 个“词元”),并应用标准 Transformer 注意力。ViT 用图像块词元上的 \(\mathcal{O}(S^2)\) 全局注意力取代了 CNN 的局部卷积。在最初的研究中,大规模预训练提高了 ViT 的竞争力,说明数据和计算如何能够弥补较弱的空间归纳偏置 (Dosovitskiy et al. 2021)。 ↩︎

  29. im2col(图像转列):im2col 式展开转换并非一种新的学习算法,而是 Caffe 和 cuDNN 等 CNN 框架与库采用的一种实现技术 (Jia et al. 2014; Chetlur et al. 2014):它通过将相互重叠的图像块展开为矩阵的列,将卷积转换为标准 GEMM 调用。其代价是内存:在简单的、完全物化的步幅为 1 的 \(K{\times}K\) 变换中,输入内部的元素最多可出现在 \(K^2\) 列中(对于 \(3{\times}3\) 滤波器为 9 次),但边界、步幅、填充、分块以及直接卷积算法会降低实际的扩展倍数。这种以内存换取实现简便性的权衡解释了为什么移动端框架(TFLite、NNAPI)更倾向于直接卷积,而拥有充足 HBM 的数据中心 GPU 则可能在能够提升吞吐量时采用面向 GEMM 的展开转换。 ↩︎

  30. 脉动阵列:该名称源于心脏有节律的收缩,数据以步调一致的“脉冲”形式流经处理器网格,直接实现了滑动窗口操作所需的高效数据复用。通过在相邻处理器之间传递输入值,可以避免卷积中的每一次乘法都付出往返访问片外 DRAM 的高昂代价。这对效率至关重要,因为一次片外内存访问的能耗可能超过一次浮点乘加运算的 100\(\times\),相对于低精度算术运算的能耗倍数则更高。↩︎

  31. TPU(张量处理单元):Google 的第一代 TPU 将矩阵乘法映射到大型脉动阵列上,以缓存和复杂控制流等通用功能为代价,换取面向特定领域的推理效率 (Jouppi et al. 2017)。这里需要理解的架构启示是定性的:当一种原语主导工作负载时,专用数据通路和局部复用可以胜过通用灵活性。硬件加速 进一步讨论了精度选择、硬件规格和性能权衡。↩︎

  32. Winograd 算法:对于使用 \(3{\times}3\) 滤波器计算的一个 \(2{\times}2\) 输出分块,该方法将 36 次直接乘法替换为 Winograd 域中的 16 次逐元素乘法,并增加额外的变换和加法。这些变换可能放大舍入误差,因此是否适用于低精度取决于具体变体、实现方式和精度要求。↩︎

  33. FlashAttention:一种 IO 感知算法 (Dao et al. 2022),通过将计算融合为单个内核,并按 SRAM 容量进行分块,避免在 HBM 中显式生成并存储完整的 \(S{\times}S\) 注意力矩阵。其结果是:按实际运行时间计获得 2–4\(\times\) 的加速,并将内存占用从 \(\mathcal{O}(S^2)\) 降至 \(\mathcal{O}(S)\),使训练所用序列的长度可达到标准注意力的 4–16\(\times\)。FlashAttention 表明,对数据移动量 \((D_{\text{vol}})\) 进行算法优化所带来的加速,可能超过增加原始计算能力 \((R_{\text{peak}})\) 所带来的加速——这具体印证了机器学习系统铁律中的数据项。↩︎

Rosenblatt, Frank. 1957. The Perceptron: A Perceiving and Recognizing Automaton. Report Nos. 85-460-1. Cornell Aeronautical Laboratory.
Horowitz, Mark. 2014. “1.1 Computing’s Energy Problem (and What We Can Do about It).” 2014 IEEE International Solid-State Circuits Conference Digest of Technical Papers (ISSCC), 10–14. https://doi.org/10.1109/isscc.2014.6757323.
Krizhevsky, Alex, Ilya Sutskever, and Geoffrey E. Hinton. 2012. “ImageNet Classification with Deep Convolutional Neural Networks.” Advances in Neural Information Processing Systems (NeurIPS) 25.
Deng, Jia, Wei Dong, Richard Socher, Li-Jia Li, Kai Li, and Li Fei-Fei. 2009. “ImageNet: A Large-Scale Hierarchical Image Database.” 2009 IEEE Conference on Computer Vision and Pattern Recognition, 248–55. https://doi.org/10.1109/cvpr.2009.5206848.
Ainslie, Joshua, James Lee-Thorp, Michiel de Jong, Yury Zemlyanskiy, Federico Lebron, and Sumit Sanghai. 2023. “GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints.” Proceedings of the 2023 Conference on Empirical Methods in Natural Language Processing, 4895–901. https://doi.org/10.18653/v1/2023.emnlp-main.298.
Kwon, Woosuk, Zhuohan Li, Siyuan Zhuang, Ying Sheng, Lianmin Zheng, Cody Hao Yu, Joseph Gonzalez, Hao Zhang, and Ion Stoica. 2023. “Efficient Memory Management for Large Language Model Serving with PagedAttention.” Proceedings of the 29th Symposium on Operating Systems Principles, 611–26. https://doi.org/10.1145/3600006.3613165.
Ioffe, Sergey, and Christian Szegedy. 2015. “Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift.” Proceedings of the 32nd International Conference on Machine Learning (ICML) 37: 448–56.
Zhang, Biao, and Rico Sennrich. 2019. “Root Mean Square Layer Normalization.” Advances in Neural Information Processing Systems (NeurIPS).
Touvron, Hugo, Thibaut Lavril, Gautier Izacard, Xavier Martinet, Marie-Anne Lachaux, Timothée Lacroix, Baptiste Rozière, et al. 2023. “LLaMA: Open and Efficient Foundation Language Models.” arXiv Preprint arXiv:2302.13971.
Touvron, Hugo, Louis Martin, Kevin Stone, Peter Albert, Amjad Almahairi, Yasmine Babaei, Nikolay Bashlykov, et al. 2023. “Llama 2: Open Foundation and Fine-Tuned Chat Models.” arXiv Preprint arXiv:2307.09288.
Jiang, A. Q., A. Sablayrolles, A. Roux, A. Mensch, B. Savary, C. Bamford, D. S. Chaplot, et al. 2024. “Mixtral of Experts.” arXiv Preprint arXiv:2401.04088.
Cho, Kyunghyun, Bart van Merrienboer, Dzmitry Bahdanau, and Yoshua Bengio. 2014. “On the Properties of Neural Machine Translation: Encoder-Decoder Approaches.” Proceedings of SSST-8, Eighth Workshop on Syntax, Semantics and Structure in Statistical Translation, 103–11. https://doi.org/10.3115/v1/w14-4012.
Dosovitskiy, Alexey, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, et al. 2021. “An Image Is Worth 16x16 Words: Transformers for Image Recognition at Scale.” International Conference on Learning Representations (ICLR).
Jia, Yangqing, Evan Shelhamer, Jeff Donahue, Sergey Karayev, Jonathan Long, Ross Girshick, Sergio Guadarrama, and Trevor Darrell. 2014. “Caffe: Convolutional Architecture for Fast Feature Embedding.” Proceedings of the 22nd ACM International Conference on Multimedia, 675–78. https://doi.org/10.1145/2647868.2654889.
Chetlur, Sharan, Cliff Woolley, Philippe Vandermersch, Jonathan Cohen, John Tran, Bryan Catanzaro, and Evan Shelhamer. 2014. “cuDNN: Efficient Primitives for Deep Learning.” arXiv Preprint arXiv:1410.0759.
Jouppi, Norman P., Cliff Young, Nishant Patil, David Patterson, Gaurav Agrawal, Raminder Bajwa, Sarah Bates, et al. 2017. “In-Datacenter Performance Analysis of a Tensor Processing Unit.” Proceedings of the 44th Annual International Symposium on Computer Architecture, ISCA ’17, 1–12. https://doi.org/10.1145/3079856.3080246.
Dao, T., D. Y. Fu, S. Ermon, A. Rudra, and C. Ré. 2022. “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness.” Advances in Neural Information Processing Systems (NeurIPS) 35: 16344–59. https://doi.org/10.52202/068431-1189.
← 中文书架