结论

结论

完整的单节点机器学习系统全景图,连接数据、模型计算、框架降层、加速器执行、模型服务、运维反馈与治理边界。

本章目的

掌握完整技术栈,能够带来哪些单一层面的专业知识无法提供的能力?

一项生产决策会贯穿整个技术栈。数据流水线决定哪些事件被视为训练信号。这些信号塑造模型架构,而架构又决定内存占用和算术强度。这些属性进一步约束硬件选择、量化策略、服务延迟、漂移监控和治理责任。单独掌握每一层,都是一项有价值的技能;将各层融会贯通,则能获得跨边界推理的能力。只懂压缩的工程师可以缩小模型,却无法预测精度损失对部署场景是否重要。只懂模型服务的工程师可以优化延迟,却无法将性能回退追溯到上游三个阶段之前的数据流水线变更。机器学习系统工程这门学科的核心,就是看清这些联系:一个团队的优化会成为另一个团队的约束。支配这些相互作用的原则——约束传播、内存墙、训练与服务的反转、分派开销、通信成本和运维生命周期——并不依附于任何特定框架、硬件世代或模型家族。技术会变化,但底层的物理约束与权衡始终存在。用数据—算法—机器的视角来看,持久的能力在于:面对一个尚不存在的系统,能够推理其数据、算法与机器约束将如何相互作用、瓶颈将在哪里出现,以及哪些设计决策将成为不可逆的选择。以系统而非组件为单位思考,正是能够构建局部的工程师与能够构建整体的工程师之间的区别。

学习目标
  • 将机器学习系统的核心原则综合为一个推理框架,用于分析数据、算法与机器约束之间的相互作用
  • 追踪数据、架构、压缩、硬件、模型服务、运维和治理决策如何在机器学习系统中传播约束
  • 运用灯塔模型推理,诊断云端、移动端、边缘端、推荐系统和 TinyML 部署中的瓶颈
  • 结合延迟预算、内存数据搬移、漂移、责任与可持续性约束,评估部署中的权衡
  • 在机群规模的协调成本占据主导地位之前,为新兴场景确立系统工程方法

机器学习系统的综合理解

将图像分类模型部署到大批移动设备上,可以说明跨层相互作用如何在生产环境中显现。架构团队选择了深度可分离卷积,将空间滤波与通道投影分解开来,从而减少算术运算。压缩团队将权重和激活量化为 INT8,以减少内存流量并使其能够容纳于片上 SRAM。模型服务团队达到了 50 ms 的 p99 延迟目标。每个团队都满足了各自的局部指标,但几周之内,特定固件和设备群组上的精度下降了四个百分点。原因在于,量化方案中的动态范围裁剪与特定固件图像预处理路径中的插值例程之间,出现了未曾预料的相互作用。没有任何组件单独发生故障;相反,数据流水线、架构、压缩方案、加速器运行时和监控基础设施在生产环境中耦合在了一起。

负责任的工程实践贯穿整个系统生命周期——规格制定、测试、运行时监控和子群体审计——而不是作为外部后处理步骤发挥作用。机器学习系统与传统软件存在根本区别,因为其统计性能在物理上无法与训练、服务和监控模型的流水线及硬件分离。

这门学科的核心是机器学习系统铁律(原则 原则(英文原版))。其中的三项——数据搬移、计算和开销——是开展定量分析的主要工程调节手段。构建智能既需要统计算法,也需要遵守硅契约(原则 原则(英文原版)),即模型与执行机器之间的物理约定。算术强度和 Roofline 建模将定性的性能直觉转化为精确的工程界限 (Williams et al. 2009)。

Williams, Samuel, Andrew Waterman, and David Patterson. 2009. “Roofline: An Insightful Visual Performance Model for Multicore Architectures.” Communications of the ACM 52 (4): 65–76. https://doi.org/10.1145/1498765.1498785.
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.
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.
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.

系统能力源于数据、算法和机器三元组(数据—算法—机器)之间的协同设计,而非孤立的算法突破。机器学习属于系统工程传统:在物理约束下协调相互依赖的组件,才能实现稳健执行。Transformer 架构引入了一个基于注意力机制的模型家族 (Vaswani et al. 2017),而 GPT-3 和 Llama 2 等大语言模型系统展示了这一家族如何扩展为现代机器学习系统的核心工作负载 (Brown et al. 2020; Touvron et al. 2023)。仅靠数学设计不足以解释其实用价值。要实现这种价值,需要将注意力机制与分布式通信拓扑、用于绕过内存带宽瓶颈的内存层次分块策略,以及低精度执行单元进行协同设计。

集成会产生具体后果。软件工程往往将“模型”视为一个权重检查点:一块 500 MB 的浮点数数据。然而,在生产环境中,权重只是真正模型的一个组成部分,而且通常并不是最脆弱的部分。基准测试精度很高的模型,如果摄入损坏的特征,也会失效;训练期间顺利收敛的模型,如果无法满足部署延迟约束,同样会失效。真正的模型是以下各部分的总和:决定学习器所见内容的数据流水线、支配优化过程的训练基础设施、承接推理的模型服务系统,以及监控统计漂移的运维闭环。优化系统,模型就会改善;忽视系统,模型就会退化。系统工程是机器学习的物理实现:系统即模型。

Checkpoint 1.1: 系统思维

系统的依赖关系、反馈回路和请求路径,使其边界能够得到检验。

集成性

整体性

端到端追踪请求,从结构上说明了同一个道理:系统边界决定模型能力,因为机器学习技术栈的每一层都会对下一层施加物理和统计约束。计算基础始于数据:数据整理(数据工程)和数据选择(数据选择)限定学习器可获取的信息,而神经表示(神经计算)与网络架构(网络架构)则将统计先验转化为具体的张量图。训练系统(模型训练)和执行框架(机器学习框架)将这些图降层映射到物理硬件上,把数学优化转化为经过调度的内核分派与内存分配。

降层映射到芯片之后,工程挑战转向重新协调物理边界。模型压缩(模型压缩)重塑精度、内存占用与延迟之间的帕累托前沿;硬件加速器(硬件加速)检验内存带宽和算术单元能否支撑执行调度;严格的基准测试(基准测试)则将真实的硬件加速效果与测量伪象区分开来。在生产环境中,模型服务基础设施(模型服务)必须在突发流量下满足尾延迟预算,运维监控(机器学习运维)负责检测统计漂移,而负责任的工程实践(负责任工程)则在总体指标掩盖局部退化时审计子群体公平性。这些领域共同构成一条连续且耦合的流水线,贯穿数据工程、训练系统、部署基础设施、运行时运维与治理。

核心经验是约束耦合:决策从来不会局限于局部。架构选择使某种压缩策略成为可能,压缩策略又约束加速器降层映射,确定服务延迟,并规定运维监控要求。MobileNetV2 的深度可分离设计旨在实现高效的移动端视觉推理 (Sandler et al. 2018),而整数算术量化使 INT8 部署成为可行的推理路径 (Jacob et al. 2018)。这一组合使移动端 NPU 执行成为可能,确立了 50 ms 的 p99 延迟约束,并要求跨异构传感器硬件和设备固件跟踪漂移。决策会向下游传播。孤立地优化单个层面的工程师,无法预测干预措施如何在整个系统中产生连锁影响。

从架构选择到 INT8 量化、p99 服务延迟以及漂移或治理责任的因果链。

架构选择会对压缩、模型服务、漂移和治理产生级联影响。

诊断这些级联相互作用,需要具体的约束映射。以代表性工作负载为分析基础,可以揭示物理界限如何决定整个技术栈中的架构选择、运行时调度和运维权衡。

灯塔模型:约束传播

五个灯塔模型(机器学习系统铁律)通过具体的执行特征,使约束传播具象化:

每种工作负载都揭示了执行谱系中一种独特的物理瓶颈:

  • ResNet-50:批大小通过在多个输入之间复用相同的滤波器权重,将图像推理从受内存限制的权重搬移转变为受计算限制的矩阵运算吞吐量问题,摊薄内存传输成本,直至算术强度越过硬件的屋脊点。
  • GPT-2/Llama:小批量自回归解码因权重复用率低而受阻于内存带宽;批处理、预填充调度和模型并行会改变起决定作用的约束。
  • MobileNetV2:深度可分离卷积与 INT8 量化以表示能力为代价,使模型能够在毫瓦级热功耗包络内的移动端 NPU 上部署。
  • DLRM:TB 级嵌入表使内存容量与内存带宽一同成为决定性约束,迫使系统围绕内存分层和稀疏访问模式开展协同设计。
  • 关键词检测(KWS)/Wake Vision:小于 1 MB 的微控制器模型需要在毫瓦级功耗预算下持续进行推理,因此不能浪费任何内存流量或分派开销。

这五种工作负载共同覆盖了从仓库级数据中心到微控制器的部署谱系,揭示了定量原则所诊断的瓶颈。沿架构、训练、优化和模型服务各环节追踪这些工作负载,可以建立一种整体视角,而这正是机器学习系统工程区别于孤立算法开发之处。

Table 1 追踪了 MobileNetV2 的这一演进过程,展示跨层约束如何汇聚于同一个工程产物。从基础约束出发,经过架构、训练、压缩、加速、模型服务和运行时运维,共七个阶段,每一项工程决策都决定了下游可用的选项。

Table 1: 灯塔模型历程(MobileNetV2):追踪一个模型在系统技术栈七个阶段中的演进,展示一个领域(例如架构)的决策如何将约束与机会传播到下游领域(例如硬件加速和监控)。
历程阶段 系统视角 MobileNetV2 实现
基础(引言) AI 三元组 受机器约束(电池/散热)限制
架构(网络架构) 算法效率 深度可分离卷积:对于具有代表性的 3×3、256 个输出通道的层,标准卷积的 FLOP 数是其 8.7×;在 ImageNet 规模下,ResNet-50 的运算量是其 13.7×
训练(模型训练) 吞吐量与延迟 针对移动端单请求延迟进行优化;数据增强可以提高稳健性
压缩(模型压缩) 探索帕累托前沿 INT8 量化:FP32 和 FP16 的单值存储量分别是 INT8 的 4× 和 2×,每次部署都需重新验证精度
加速(硬件加速) 遵守硅契约 将内核映射到移动端 NPU(例如 Apple Neural Engine),以最大化硬件利用率
模型服务(模型服务) 遵守延迟预算 \(\text{p99} < 50\) ms 约束;优化预处理(调整大小/归一化),避免 CPU 瓶颈
运维(机器学习运维) 管理系统熵 漂移监控:检测分布偏移,并在异构设备群体和不同光照条件下跟踪群组级精度

一行中的决策决定下一行中的选项:架构选择(深度可分离卷积)使压缩策略(INT8 量化)成为可能,而压缩策略又使移动端 NPU 加速变得可行。这种约束传播普遍存在于机器学习工作负载中。要形式化描述这些权衡,需要定量原则,涵盖精确的物理界限、经验分解,以及依赖特定假设的诊断方法。

十三项定量原则

推理机器学习系统的行为需要定量工具。这十三项定量原则有意结合了精确的数学界限、工程分解、拟合的经验模型、政策约束和设计启发式。Table 2 汇总了横跨四个系统阶段的全部十三项原则。其效用取决于在所声明的假设范围内严格应用,而不是将每一种关系都视为恒定不变的物理定律。

Table 2: 十三项定量原则:每项工具都出现在其支配性约束或诊断用途首次显现的部分。这组原则涵盖界限、分解、拟合模型、策略要求和启发式方法。每一行仅在其明确的假设下才有用;它们共同为系统设计、优化和部署提供了一套共享的分析术语,而非一组普遍成立的不变量。
# 原则 部分 核心方程/陈述 预测内容
原则(英文原版) 数据即代码原则 I:基础 行为 \(=f\)(数据, 算法, 代码, 随机性) 数据改变行为;其他输入也有影响
原则(英文原版) 数据引力原则 I:基础 当重复传输成本超过计算资源部署成本时,将计算移向数据 取决于数据量、复用程度、网络和计算资源的可迁移性
原则(英文原版) 机器学习系统铁律 II:构建 \(T_{\text{seq}}=D_{\text{vol}}/\text{BW}+O/(R_{\text{peak}}\eta_{\text{hw}})+L_{\text{lat}}\);阶段重叠程度使总时间介于各项最大值与总和之间 各阶段可能累加,也可能重叠
原则(英文原版) 芯片契约 II:构建 \(I_{\text{ridge}}=R_{\text{peak}}/\text{BW}\);比较 \(I_{\text{model}}\) 与 \(I_{\text{ridge}}\) 判断运行受带宽限制还是受计算限制
原则(英文原版) 帕累托前沿 III:优化 \(\nexists c'\ne c:\,[\forall k\,M_k(c')\ge M_k(c)]\land[\exists j\,M_j(c')>M_j(c)]\) 不存在支配前沿上某一点的其他配置
原则(英文原版) 算术强度定律 III:优化 \(R_{\text{attain}} \le \min(R_{\text{peak}},\; I \times \text{BW})\) 增加计算能力无法提高带宽所决定的性能上限
原则(英文原版) 能耗—数据移动不变量 III:优化 \(E_{\text{total}}=\sum_j N_jE_j\);DRAM/FLOP 成本比:173–582× 总能耗取决于事件次数及其成本
原则(英文原版) 阿姆达尔定律 III:优化 \(\text{Speedup} = \frac{1}{(1-f_{\text{parallel}}) + \frac{f_{\text{parallel}}}{S_{\text{parallel}}}}\) 串行部分的占比限定了所有并行化收益的上限
原则(英文原版) 验证鸿沟 IV:部署 \(\Pr_{(X,Y)\sim P_{\text{deploy}}}[d(f(X),Y)\le\tau]\ge1-\epsilon\) 需明确距离、容差、总体和置信度
原则(英文原版) 统计漂移诊断 IV:部署 \(\text{Accuracy}(t)\approx\text{Accuracy}_0-\lambda\mathcal{D}(P_t\Vert P_0)\) 属于局部拟合;漂移不一定降低质量
原则(英文原版) 训练—服务偏差诊断 IV:部署 \(S_{\text{skew}}=\mathbb{E}_{X\sim P_{\text{deploy}}}[d(f_{\text{serve}}(X),f_{\text{train}}(X))]\) 输出不一致表明存在风险,并不意味着准确率损失
原则(英文原版) 延迟预算原则 IV:部署 \(T_q\le L_{\text{budget}}\) 产品 SLO 决定 \(q\) 及其预算
原则(英文原版) 偏差反馈模型 IV:部署 \(\Delta_g(k)\approx\Delta_g(0)\alpha_{\text{fb}}^k\),其中 \(\alpha_{\text{fb}}\) 通过拟合得到 反馈可能放大危害;需测量并干预

这十三项原则并非相互独立的公理。它们构成一个由单一元原则联结的整合框架:复杂度守恒启发式。1 从一个接口中消除的复杂度往往会在系统的其他部分重新出现,但这不是物理守恒定律,也不意味着每一次简化都会产生等量的补偿性成本。其价值在于诊断:简化某个组件之后,应检查验证、状态、协调或运维负担在哪些地方发生了变化。检验标准是:这些原则能否从数据、模型、硬件和部署的视角解释同一组灯塔模型的瓶颈,同时彼此不矛盾。

基础:复杂度从何而来(原则 1–2)

数据工程 中阐述的数据即代码原则(原则(英文原版))和数据引力启发式(原则 原则(英文原版)),将数据确立为主要的逻辑程序和物理锚点。运行时行为由数据、算法和实现共同决定,而将计算部署到数据附近,需要权衡传输量、复用频率、网络带宽以及计算资源的可迁移性。模型行为与架构直接继承这一数据基础所施加的约束。

灯塔模型展示了这两项原则。ResNet-50 和 GPT-2 的能力来自模型架构与大规模训练语料的结合。DLRM 的 TB 级嵌入表使内存容量成为首要设计约束,要求围绕数据的实际物理位置设计执行系统。将计算部署到数据附近的做法在各种部署环境中反复出现,正是因为移动规模庞大、复用率低的数据集会使互连链路饱和。

构建:复杂度如何转化为计算(原则 3–4)

机器学习系统铁律(原则 原则(英文原版))和芯片契约(原则 原则(英文原版))支配执行效率。铁律的三项分解(机器学习系统铁律)将数据移动、计算和开销区分开来;芯片契约则揭示,在给定的模型架构与硬件组合上,哪一项限制了性能。不同工作负载处于不同的运行区间:批量 ResNet-50 推理使计算单元饱和,小批量 Llama 解码因内存带宽受限而停滞,DLRM 耗尽内存容量,而 MobileNetV2 通过重构张量运算,使其能够在移动 NPU 的限制内执行。如 瓶颈诊断 中的映射所示,诊断执行路径受计算、带宽还是容量限制,决定了哪些优化能够带来加速,哪些只会浪费工程投入。当工程师直接针对起约束作用的那一项进行优化,而非均匀分配精力时,训练延迟的降幅最大(模型训练)。

优化:约束如何塑造权衡(原则 5–8)

四项优化原则构成一条紧密耦合的诊断链。帕累托前沿(原则 原则(英文原版))在统一各目标的优化方向后识别非支配权衡:量化以降低数值精度为代价减少内存流量,剪枝以降低模型容量为代价提高速度,蒸馏则以增加训练计算量为代价提高推理效率。算术强度定律(原则 原则(英文原版))用于诊断理想性能上限由计算能力还是带宽决定。能耗—数据移动不变量(原则 原则(英文原版))将单次事件成本与事件次数结合起来:在参考硬件常数下,一次 DRAM 访问的能耗约为一次 FP32/FP16 算术运算的 173–582×,但哪一类事件主导工作负载的总能耗,取决于各类事件发生的次数。阿姆达尔定律(原则 原则(英文原版))限定了任何并行化收益的上限,解释了为何数据加载和预处理会在高度优化的系统中成为瓶颈。

MobileNetV2(网络架构)同时平衡这四项原则。深度可分离卷积重塑了帕累托前沿 (Sandler et al. 2018)。INT8 量化通过减少内存流量来提高算术强度,从而利用算术强度定律 (Jacob et al. 2018)。由此产生的节能效果符合能耗—数据移动不变量,而当主机侧预处理仍未获得加速时,阿姆达尔定律会限制端到端加速比。KWS 等微控制器工作负载进一步收紧了这些权衡,它们在不足一兆字节的内存条件下运行,没有任何容纳运行浪费的余地。

Jacob, Benoit, Skirmantas Kligys, Bo Chen, Menglong Zhu, Matthew Tang, Andrew Howard, Hartwig Adam, and Dmitry Kalenichenko. 2018. “Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference.” 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition, 2704–13. https://doi.org/10.1109/cvpr.2018.00286.

部署:现实如何使假设失效(原则 9–13)

部署原则针对的是台架测试无法排除的失效:系统可能在台架上正常运行,却在生产环境中静默失效。验证鸿沟(原则 原则(英文原版))意味着,统计验证仅在明确的部署总体、任务距离、容差、目标误差以及有限样本置信度程序下成立;测试估计的是行为,而非证明系统对未来每一个输入都正确。统计漂移诊断(原则 原则(英文原版))能够检测分布变化,却不能确定准确率会下降、保持不变还是提高,因此,局部退化曲线只有根据实际结果拟合后才有效。训练—服务偏差诊断(原则 原则(英文原版))同样是一项风险指标,而非普遍适用的准确率损失方程,尽管预处理或数值差异仍可能导致质量变化。延迟预算(原则 原则(英文原版))在产品要求选定的分位数上约束模型服务,该分位数可以是 p95、p99 或其他尾部度量。最后,偏差反馈模型(原则 原则(英文原版))可以表示差异的放大,但指数递推要求反馈因子经过测量、近似恒定,并且不存在有效干预。

这五项部署原则支配着 机器学习运维 中考察的运维工具:监控基础设施、漂移检测、特征存储和按子群体拆分的指标,都是为了揭示静默失效并触发纠正措施。即使推荐系统取得了很高的离线准确率,当训练—服务偏差破坏特征流水线时,仍然需要一致性检查(原则 原则(英文原版));当用户行为随季节变化时,则需要结果审计(原则 原则(英文原版))。大语言模型服务必须通过连续批处理和推测解码(模型服务)约束尾延迟,避免违反产品服务级别目标。同样,自动化信贷模型可能满足吞吐量和收敛目标,却系统性地加剧服务不足群体所面临的差异,因此需要按群体拆分的监控来阻断反馈回路(原则 原则(英文原版))。

整合框架

这十三项原则不是需要依次应用的检查清单。它们构成一个相互约束的网络。复杂度守恒启发式促使工程师寻找局部简化将负担转移到了何处。

将模型从 FP16 量化为 INT8,展示了这些相互约束如何发挥作用。这一项干预沿着帕累托前沿(原则 原则(英文原版))进行取舍,以降低数值精度为代价减少内存流量。其影响贯穿整个技术栈:量化改变模型的芯片契约(原则 原则(英文原版)),移动其在算术强度曲线上的运行点(原则 原则(英文原版)),并改变其能耗特征(原则 原则(英文原版))。在部署阶段,延迟预算(原则 原则(英文原版))决定所得加速是否满足服务级别目标(SLO),而验证鸿沟(原则 原则(英文原版))则要求验证经底层转换后的服务计算图是否保持了压缩测试中测得的经验准确率。

这一追踪过程不要求每项原则同时适用。它展示了当一项决策从模型表示转向硬件执行,再转向生产验证时,相关原则如何开始发挥作用。数据布局影响模型能够在哪里运行,阿姆达尔定律限制更快的内核能够在多大程度上改善整个请求路径,验证限定由此产生的准确率损失,而结果监控则检验已经验证的行为在部署后是否持续成立。工程师的任务是追踪在技术栈中被转移的成本,而不是假定复杂度会直接消失。

评估一项部署提案,可以使这一约束网络具体化。

Checkpoint 1.2: 应用这些原则

一位同事提议将你的模型从 FP32 量化为 INT8,以降低模型服务成本。

追踪相关原则

Figure 1 描绘了这一相互约束的循环。基础、构建、优化和部署四个阶段围绕着一个表示复杂度守恒启发式的中心枢纽。箭头追踪工程选择如何向下游传播:构建阶段的约束决定优化策略,而统计漂移、特征偏差和结果退化等运行时信号则反馈到基础阶段。管理这一循环,需要将被转移的复杂度引导至能够高效处理它的层。

从部署到基础的反馈回路是生产工程的核心。原则 9 至 13 揭示了能够触发针对性补救措施的信号:金丝雀发布回滚、回退启发式、数据集扩充、模型重新训练或内核重新调优。当异常出现时,工程师应诊断根本原因,而非触发未经校准的回滚。这一循环支配单个系统的设计:目标不是罗列未来所有可能的架构,而是在运维失效不断累积之前,使反馈回路可观测。

\begin{tikzpicture}[line join=round,font=\sffamily]

\tikzset{
Box/.style={align=flush center,
    inner sep=4pt,
    node distance=1.4,
    draw=OrangeLine,
    line width=0.75pt,
    rounded corners,
    fill=OrangeL!30,
    text width=25mm,
    minimum width=25mm, minimum height=10mm
  },
Box2/.style={Box, draw=VioletLine, fill=VioletL2!70,align=left,
    text width=36mm, minimum width=36mm, minimum height=10mm
  },
  }

\tikzset{%
planet/.style = {circle, draw=yellow!50!red!90,semithick, fill=yellow!30,line width=1.5pt,
                    font=\sffamily\bfseries,
                    minimum size=24mm, inner sep=1mm,align=flush center},
satellite/.style = {circle, draw=none, semithick, fill=#1!10,
                    text width=26mm, inner sep=1pt, align=flush center,minimum size=20mm,minimum height=12mm},
TxtC/.style = {font=\small\sffamily,text width=44mm,align=flush center},
arr/.style = {-{Triangle[length=3mm,width=6mm]}, color=#1!60,
                    line width=3mm, shorten <=1mm, shorten >=1mm},
LineA/.style = {violet!60,{Circle[line width=1.5pt,fill=white,length=7.5pt]}-,line width=2.0pt,shorten <=-4pt},
LineAA/.style={violet!30,dashed, line width=1.0pt,{-{Triangle[width=1.0*6pt,length=1.6*6pt]}},shorten <=3pt,shorten >=2pt}
}

\tikzset{pics/brain/.style = {
        code = {
        \pgfkeys{/channel/.cd, #1}
\begin{scope}[local bounding box=BRAIN,scale=\scalefac, every node/.append style={transform shape}]
\draw[fill=\filllcolor,line width=\Linewidth](-0.3,-0.10)to(0.08,0.60)
to[out=60,in=50,distance=3](-0.1,0.69)to[out=160,in=80](-0.26,0.59)to[out=170,in=90](-0.46,0.42)
to[out=170,in=110](-0.54,0.25)to[out=210,in=150](-0.54,0.04)
to[out=240,in=130](-0.52,-0.1)to[out=300,in=240]cycle;
\draw[fill=\filllcolor,line width=\Linewidth]
(-0.04,0.64)to[out=120,in=0](-0.1,0.69)(-0.19,0.52)to[out=120,in=330](-0.26,0.59)
(-0.4,0.33)to[out=150,in=280](-0.46,0.42)
%
(-0.44,-0.03)to[bend left=30](-0.34,-0.04)
(-0.33,0.08)to[bend left=40](-0.37,0.2) (-0.37,0.12)to[bend left=40](-0.45,0.14)
(-0.26,0.2)to[bend left=30](-0.24,0.13)
(-0.16,0.32)to[bend right=30](-0.27,0.3)to[bend right=30](-0.29,0.38)
(-0.13,0.49)to[bend left=30](-0.04,0.51);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.23,0.03)--(-0.15,-0.03)--(-0.19,-0.18)--(-0.04,-0.28);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.17,0.13)--(-0.04,0.05)--(-0.06,-0.06)--(0.14,-0.11);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.12,0.23)--(0.31,0.0);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.07,0.32)--(0.06,0.26)--(0.16,0.33)--(0.34,0.2);
\draw[rounded corners=0.8pt,line width=1.5*\Linewidth,\drawcircle,-{Circle[fill=\filllcolor,length=4.15pt]}](-0.01,0.43)--(0.06,0.39)--(0.18,0.51)--(0.31,0.4);
\end{scope}
     }
  }
}

%brick
\tikzset{
  cigla/.style={ inner sep=0pt,anchor=west,
    node distance=1.4pt,
    draw=none,
    line width=0.1pt,
    rounded corners=1pt,
    fill=\filllcolor,
    minimum width=4mm, minimum height=2mm
  },
    cigla1/.style={cigla,fill=\filllcirclecolor},
pics/brick/.style = {
        code = {
        \pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\path[clip] (-1.05,-0.52)rectangle (0.71,0.45);
\node[cigla](C1) at (-1.03,-0.4){};
\node[cigla1,right= of C1](C2){};
\node[cigla,right= of C2](C3){};
\node[cigla1,right= of C3](C4){};
%
\node[cigla,above right= of C1,anchor=south](C11){};
\node[cigla1,right= of C11](C12){};
\node[cigla,right= of C12](C13){};
\node[cigla1,right= of C13](C14){};
%
\node[cigla,above right= of C11,anchor=south](C21){};
\node[cigla1,right= of C21](C22){};
\node[cigla,right= of C22](C23){};
%
\node[cigla,above right= of C21,anchor=south](C31){};
\node[cigla1,right= of C31](C32){};
\node[cigla,right= of C32](C33){};
\end{scope}
    }
  }
}
%vaga
\tikzset{
pics/vaga/.style = {
        code = {
        \pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\node[rectangle,minimum width=2mm,minimum height=22mm,
draw=none, fill=\filllcolor,line width=\Linewidth](1R) at (0,-0.95){};
\fill[fill=\filllcolor!60!black](230:2.8)arc(230:310:2.8)--cycle;%circle(2.9);
%LT
\node [semicircle, shape border rotate=180,  anchor=chord center,
      minimum size=11mm, draw=none, fill=\filllcirclecolor](LT) at (-2,-0.5) {};
\node [circle,  minimum size=4mm, draw=none, fill=\filllcirclecolor](T1) at (-2,1.25) {};
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T1)--(LT);
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T1)--(LT.30);
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T1)--(LT.150);
%DT
\node [semicircle, shape border rotate=180,  anchor=chord center,
      minimum size=11mm, draw=none, fill=\filllcirclecolor!70!black](DT) at (2,-0.5) {};
\node [circle,  minimum size=4mm, draw=none, fill=\filllcirclecolor!70!black](T2) at (2,1.25) {};
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T2)--(DT);
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T2)--(DT.30);
\draw[draw=\drawcolor,line width=1.2*\Linewidth,shorten <=3pt,shorten >=3pt](T2)--(DT.150);
%
\node[draw=none,rectangle,minimum width=32mm,minimum height=1.5mm,inner sep=0pt,
fill=\filllcolor!60!black]at(0,1.25){};
\node[draw=white,fill=\filllcolor,line width=2*\Linewidth,ellipse,minimum width=9mm,  minimum height=15mm](EL)at(0,0.85){};
\node[draw=white,fill=\filllcolor!60!black,line width=2*\Linewidth,circle,minimum size=10mm](2C)at(0,2.05){};
\end{scope}
    }
  }
}
%llm
\tikzset{
pics/llm/.style = {
        code = {
        \pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\node[circle,minimum size=12mm,draw=\drawcolor, fill=\filllcolor!70,line width=0.5*\Linewidth](C\picname) at (0,0){};
\def\startangle{90}
\def\radius{1.15}
\def\radiusI{1.1}
\foreach \i [evaluate=\i as \j using \i+1] [count =\k] in {0,2,4,6,8} {
\pgfmathsetmacro{\angle}{\startangle - \i * (360/8)}
\draw[draw=black,-{Circle[black ,fill=\filllcirclecolor,length=5.5pt,line width=0.5*\Linewidth]},line width=1.5*\Linewidth](C\picname)--++(\startangle - \i*45:\radius) ;
\node[circle,draw=black,fill=\filllcirclecolor!80!red!50,inner sep=3pt,line width=0.5*\Linewidth](2C\k)at(\startangle - \j*45:\radiusI) {};
}
\draw[line width=1.5*\Linewidth](2C1)--++(-0.5,0)|-(2C2);
\draw[line width=1.5*\Linewidth](2C3)--++(0.5,0)|-(2C4);
\node[circle,minimum size=12mm,draw=\drawcolor, fill=\filllcolor!70,line width=0.5*\Linewidth]at (0,0){};
\end{scope}
    }
  }
}
%battery
\tikzset{
pics/battery/.style = {
        code = {
        \pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape}]
\node[rectangle,minimum width=35mm,minimum height=8mm,draw=\drawcolor,
rounded corners=4pt,fill=\filllcirclecolor,line width=\Linewidth](2R\picname) at (1,0){};
\node[rectangle,minimum width=45mm,minimum height=22mm,draw=\drawcolor,
rounded corners=4pt,fill=\filllcolor,line width=\Linewidth](R\picname) at (0,0){};
\node[rectangle,minimum width=5mm,minimum height=18mm,draw=none,
fill=green,line width=\Linewidth](3R\picname) at ($(R\picname.west)!0.5!(R\picname.east)$){};
\node[rectangle,minimum width=5mm,minimum height=18mm,draw=none,
fill=green,line width=\Linewidth](3R\picname) at ($(R\picname.west)!0.33!(R\picname.east)$){};
\node[rectangle,minimum width=5mm,minimum height=18mm,draw=none,
fill=green,line width=\Linewidth](3R\picname) at ($(R\picname.west)!0.16!(R\picname.east)$){};

\end{scope}
    }
  }
}
%rocket
\tikzset{
pics/rocket/.style = {
        code = {
        \pgfkeys{/channel/.cd, #1}
\begin{scope}[shift={($(0,0)+(0,0)$)},scale=\scalefac,every node/.append style={transform shape},line cap = round]
%vrh
\draw[fill=\filllcolor,draw=\drawcolor,line width=\Linewidth](-0.26,0.5)to[bend right=12](0.26,0.5)to[bend right=7] (0,0.85)to[bend right=7] cycle;
%krila
\draw[fill=\filllcolor!70!red,draw=\drawcolor,line width=\Linewidth,rounded corners=1pt](-0.2,-0.7)--(-0.45,-0.9)--(-0.567,-0.4)--(-0.3,-0.17)--cycle;
\draw[fill=\filllcolor!70!red,draw=\drawcolor,line width=\Linewidth,rounded corners=1pt](0.2,-0.7)--(0.45,-0.9)--(0.567,-0.4)--(0.3,-0.17)--cycle;
%rep
\draw[fill=\filllcolor!70!green,draw=\drawcolor,line width=\Linewidth](0.16,-0.76)--(0.22,-0.9)--(-0.2,-0.9)--(-0.15,-0.76)--cycle;
%body
\draw[fill=\filllcolor,draw=\drawcolor,line width=\Linewidth](-0.2,-0.7)--(0.2,-0.7)to[out=75,in=320](0,0.85)to[out=220,in=105] cycle;
%krug
\node[circle,draw=\drawcolor,minimum size=4mm,fill=\filllcirclecolor,line width=\Linewidth]{};
\draw[draw=\drawcolor,line width=1.5*\Linewidth](0,-0.99)--(0,-1.3);
\draw[draw=\drawcolor,line width=1.5*\Linewidth](-0.11,-0.99)--(-0.11,-1.2);
\draw[draw=\drawcolor,line width=1.5*\Linewidth](0.11,-0.99)--(0.11,-1.2);
\end{scope}
    }
  }
}
\pgfkeys{
  /channel/.cd,
   Depth/.store in=\Depth,
  Height/.store in=\Height,
  Width/.store in=\Width,
  filllcirclecolor/.store in=\filllcirclecolor,
  filllcolor/.store in=\filllcolor,
  drawcolor/.store in=\drawcolor,
  drawcircle/.store in=\drawcircle,
  scalefac/.store in=\scalefac,
  Linewidth/.store in=\Linewidth,
  picname/.store in=\picname,
  filllcolor=BrownLine,
  filllcirclecolor=violet!20,
  drawcolor=black,
  drawcircle=violet,
  scalefac=1,
  Linewidth=0.5pt,
  Depth=1.3,
  Height=0.8,
  Width=1.1,
  picname=C
}

\def\radius{3.9}
\def\startangle{90}

\foreach \i/\j/\sho [count=\k from 0] in {
%green!79!black
white/{\textbf{}\\ }/15pt,
%magenta!60!
white/{\textbf{}\\ }/15pt,
%gray
white/{\textbf{}\\}/15pt,
%cyan
white/{\textbf{}\\ }/15pt
}
{
%Satelit
\pgfmathsetmacro{\angle}{\startangle - \k * (360/4)}
\node (s\k) [satellite=\i, font=\footnotesize\sffamily] at (\angle:\radius) {};
 \node[TxtC,below=0pt of s\k]{\j};
}
%logos
%brick
\pic[shift={(0.15,0.15)}] at  (s3) {brick={scalefac=1.1,picname=1,filllcolor=red!70!black!80,Linewidth=1.0pt,filllcirclecolor=red!90!black!50}};
%llm
\pic[shift={(0,0)}] at  (s0){llm={scalefac=0.9,drawcolor=BlueLine,filllcolor=BlueLine!10!, Linewidth=1.25pt,filllcirclecolor=red}};
%brain
\pic[shift={(0.1,-0.16)}] at  (s0){brain={scalefac=0.8,picname=1,filllcolor=orange!30!, filllcirclecolor=cyan!55!black!60, Linewidth=0.5pt}};
%battery
\pic[shift={(0,0)}] at  (s1){battery={scalefac=0.38,picname=1, drawcolor=BrownLine,filllcolor=BrownLine!10!, Linewidth=1.5pt,filllcirclecolor=BrownLine}};
%rocket
\pic[shift={(0,0.2)}] at  (s2){rocket={scalefac=1.1,picname=1, drawcolor=black,filllcolor=cyan!10!, Linewidth=1.0pt,filllcirclecolor=red}};
%center
\node[circle, draw=BrownLine, dashed,thick, fill=none,minimum size=26mm](CE)at(0,0){};
 \node[TxtC,below=0pt of CE]{复杂度\\守恒};
 \pic[shift={(0,0)}] at  (0,0){vaga={scalefac=0.35,picname=1,filllcolor=BlueLine,  Linewidth=1.0pt,filllcirclecolor=orange}};
\def\ra{26mm}
\foreach \i [count=\k from 0] in{360,320,140,135}{
\pgfmathtruncatemacro{\newX}{\i + 90} %
\draw[line width=2.6pt,violet]
   (s\k)+(\i:0.5*\ra) arc[start angle=\i, end angle=\newX, radius=0.5*\ra];
}
 \draw[LineA](s0.35)--++(0:1)coordinate(MA);
 \node[Box,anchor=west](FO)at(MA){\textbf{构建}\\(模型)};
 \draw[LineA](s1.355)--++(345:1)coordinate(ST);
 \node[Box,anchor=west](PR)at(ST){\textbf{优化}\\(硬件)};
 \draw[LineA](s2.185)--++(200:3.25)coordinate(DE);
 \node[Box,anchor=west](DEP)at(DE){\textbf{部署}\\(运维)};
 \draw[LineA](s3.180)--++(180:3.9)coordinate(FO);
 \node[Box,anchor=west](FND)at(FO){\textbf{基础}\\(数据)};
%
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (60:\radius)
arc[radius=\radius, start angle=60, end angle= 16];
\coordinate (AR1) at (38:\radius);
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (340:\radius)
arc[radius=\radius, start angle=340, end angle= 290];
\coordinate (AR2) at (315:\radius);
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (240:\radius)
arc[radius=\radius, start angle=240, end angle= 200];
\coordinate (AR3) at (225:\radius);
\draw[-{Triangle[width=18pt,length=8pt]}, line width=10pt,cyan!40] (160:\radius)
arc[radius=\radius, start angle=160, end angle= 114];
\coordinate (AR4) at (137:\radius);
%
 \draw[LineA](AR1)--++(0:1.3)coordinate(MA);
 \node[Box2,anchor=west]at(MA){3. 机器学习系统铁律\\
4. 硅契约};
 \draw[LineA](AR2)--++(340:1.6)coordinate(MA1);
 \node[Box2,anchor=west]at(MA1){5. 帕累托前沿\\
6. 算术强度\\
7. 能量与数据移动\\
8. 阿姆达尔定律};
 \draw[LineA](AR3)--++(180:6.5)coordinate(MA2);
 \node[Box2,anchor=west]at(MA2){9. 验证鸿沟\\
10. 统计漂移\\
11. 偏斜诊断\\
12. 延迟预算\\
13. 偏差反馈};
 \draw[LineA](AR4)--++(180:6.5)coordinate(MA3);
 \node[Box2,anchor=west]at(MA3){1. 数据即代码\\
2. 数据引力};
 \end{tikzpicture}
Figure 1: 机器学习系统的循环(13 项原则):围绕复杂度守恒启发式组织的四阶段系统工程生命周期。各阶段连接成一个反馈循环,十三项原则沿阶段转换分组,涵盖界限、分解、拟合模型、策略要求和设计启发式,其适用假设均须检查。

依据四项原则逐一审视量化提案,是一轮诊断过程;当瓶颈并非某项优化提案,而是为单个生成词元提供服务的成本时,同样的思维习惯也适用。

Napkin Math 1.1: 一个词元的成本
问题:将机器学习系统铁律(原则 原则(英文原版))和算术强度定律(原则 原则(英文原版))应用于 Llama 2 70B 这样的、具有 70-billion 个参数的模型,为其一个词元提供服务,并将其 FP16 权重均匀分片到两块 NVIDIA H100 上,此时哪个理想化时间下界更大:内存传输还是峰值计算?AI 硬件速查表(现代参考) 提供了 H100 的规格。本计算不包括 KV 缓存流量、激活值、随上下文变化的针对 KV 的注意力计算 FLOPs、互连通信以及调度开销。

物理量:

  • 移动的模型权重字节总量 \((D_{\text{vol}})\):70 billion 个参数 \(\times\) 2 字节(FP16)=
  • 计算量 \((O)\):每个词元 \(O \approx 2 \times P =\) 140 GFLOP,其中 \(P\) 为参数数量。
  • 硬件:两块 H100,聚合 \(\text{BW}\) = 6.70 TB/s,FP16 的 \(R_{\text{peak}} \approx\) 1978 TFLOP/s。

数学计算:

  • 数据移动时间:\(T_{\text{mem}} = \frac{140 \text{ GB}}{6700 \text{ GB/s}} \approx 20.9 \text{ ms}\)
  • 计算时间:\(T_{\text{comp}} = \frac{140 \times 10^9 \text{ FLOP}}{1978 \times 10^{12} \text{ FLOP/s}} \approx 0.07 \text{ ms}\)

系统洞见:

理想化内存传输时间下界 \(T_{\text{mem}}\) 是峰值计算时间下界 \(T_{\text{comp}}\) 的 295.2×。在这一批大小为 1 的模型中,解码受到严重的带宽限制(算术强度 \(\approx 1\) FLOP/字节)。由于每个 2 字节的 FP16 权重都需要从高带宽内存中取出,与当前词元的激活值执行一次乘加运算(\(2\text{ FLOPs}\)),因此算术强度为 \(\frac{2\text{ FLOPs}}{2\text{ bytes}} = 1\text{ FLOP/byte}\),远低于双 H100 的脊点 \(\approx 295\text{ FLOP/byte}\)。张量核心超过 \(99\%\) 的周期都在等待数据。批处理可以增加复用,而量化可以减少权重传输流量。仅优化计算执行,可以使实际计算时间向 0.07 ms 的下界逼近,但无法降低 20.9 ms 的内存传输时间下界。

在 H100 图表中,理想化的批大小为 1 的 Llama 解码点位于 Roofline 脊点左侧。

在这一批大小为 1 的下界模型中,解码位于 Roofline 脊点左侧,处于带宽受限区间。

这项 Roofline 评估展示了物理界限如何发挥诊断工具的作用,而非仅作为抽象的分类体系。在构建基础、面向规模开展工程设计以及应对生产环境现实这三个核心工程领域中,这些界限、经验模型和启发式方法共同约束着系统设计与运行稳定性。

实践中的原则

如果一个团队熟记全部十三项原则,却无法识别其假设,也无法将其应用于实际部署决策,那么这个团队就一无所获。对于贯穿机器学习生命周期的三个领域——构建技术基础、面向规模开展工程设计以及应对生产环境现实——检验标准都是相同的。系统思维能够建立孤立的组件分析所无法建立的联系。

构建技术基础

数据即代码原则(原则(英文原版))将数据集和数据流水线实际上充当可执行程序这一事实落实到工程实践中(数据工程),呼应了 Karpathy 的 Software 2.0 框架 (Karpathy 2017),同时也承认服务逻辑和算法状态同样决定系统行为。神经计算原语(神经计算)决定矩阵乘法的算术强度,而算术强度相对于硬件脊点的位置决定执行过程是受带宽限制还是受计算限制。框架选择(机器学习框架)直接落实硅契约:每个运行时引擎都会约束图优化、内存布局、后端目标支持以及下游部署路径。在选择框架时若不评估这些执行边界,就可能阻断高性能推理路径。

Karpathy, Andrej. 2017. Software 2.0. Medium.

基础选择(整理哪些数据、依赖哪些计算原语、采用哪个框架)会传导至后续的工程决策。当系统必须扩展到单机之外时,这种传导尤为明显:此时,铁律中的三项从芯片级物理量扩展为集群级约束。

面向规模开展工程设计

分布式训练系统展示了铁律的实际作用(模型训练):数据并行以集合通信为代价,扩展跨加速器的计算吞吐量;混合精度通过以 FP16 或 BF16 表示张量,将内存数据移动量减半;激活检查点则以重新计算换取内存容量。每种技术都针对铁律中的某一项。同样,模型压缩(模型压缩)直接探索帕累托前沿:MobileNetV2 的 INT8 量化和 DLRM 的嵌入剪枝以数值精度或参数容量换取带宽节省,而算术强度定律则决定这种削减能否在目标硬件上转化为实际加速。

然而,构建和优化模型只完成了工程挑战的一半。另一半从模型离开训练集群、进入生产环境的那一刻开始:在生产环境中,统计要求、拟合得到的诊断方法和 SLO 策略共同约束系统行为,而在基准测试中有效的优化必须经受真实流量不可预测性的考验。

应对生产环境的现实

从训练转向推理往往会改变优化目标:训练追求在数天的时间尺度上最大化吞吐量,而交互式推理可能优化以毫秒计的某个选定尾延迟分位数。这里的示例场景采用 50 ms 的平均延迟和 2,000 ms 的 p99 延迟,因此所选尾延迟是平均值的 40\(\times\);其他产品可能规定 p95、p99.9,或针对不同请求类别分别设定截止时间。尾延迟分析 揭示了平均延迟为何会掩盖那些主导用户体验的请求 (Dean and Barroso 2013)。在机器学习服务中,尾延迟突增可能源于基于 Python 的推理框架中的垃圾回收暂停、不均匀流量下未能形成最优批次的动态批处理,或自回归生成中长提示或长输出所带来的、远多于典型短响应的计算工作量。

Dean, Jeffrey, and Luiz André Barroso. 2013. “The Tail at Scale.” Communications of the ACM 56 (2): 74–80. https://doi.org/10.1145/2408776.2408794.

对比平均延迟与 p99 延迟的页边插图。

平均延迟掩盖尾部;选定的尾延迟分位数决定 SLO。

技术性能只界定了运行范围的一部分;系统设计还涵盖社会影响(负责任工程)。验证要求在持续审计吞吐量的同时,持续审计违反公平性要求的情况:跟踪不同人口群体的预测分布,检测偏差随时间的放大(原则 原则(英文原版)),并对各子群体之间的差异发出告警。子群体漂移监控至关重要,因为即使总体指标保持稳定,代表性不足人群的准确率也可能急剧下降。负责任的工程是一项运行要求,而非外部伦理审查——它是一项首要设计约束,须遵循与延迟和吞吐量相同的度量规范。

这三个领域表明,十三项原则是务实的工具,而非僵化的公理。随着机器学习系统扩展到异构部署目标、应对对抗性条件并追求日益复杂的组合方式,问题在于这些原则的假设接下来会在何处构成约束。

未来方向

当这一框架能够预测约束接下来可能在何处起作用时,它最为有用。三个领域使相同的物理规律承受越来越大的压力:跨多种情境的部署、对抗性条件下的鲁棒性 (Goodfellow et al. 2015),以及其失效会造成公共后果的社会应用。第四个前沿是组合多个模型、工具和验证器,或扩展到单机之外的系统;它延伸了同一分析视角,而非取代它。

Goodfellow, I. J., J. Shlens, and C. Szegedy. 2015. “Explaining and Harnessing Adversarial Examples.” International Conference on Learning Representations (ICLR).

将原则应用于新兴部署情境

部署的多样性检验了同一个定量框架能否解释资源条件迥异的系统。云端提供充足的电力和集中的硬件,边缘与移动设备受延迟和电池预算约束,而 TinyML 与嵌入式系统则将同一设计问题压缩到千字节和毫瓦尺度。生成式 AI 并非第五种部署环境;它是一类会给上述四种环境都带来压力的工作负载。

在云端,起决定性约束作用的决策是如何将充足的硬件转化为有效吞吐量,同时避免数据移动、容量或成本成为主导因素。ResNet-50 等稠密工作负载通过算子核融合、混合精度训练和梯度压缩来提高 GPU 利用率,而 DLRM 类推荐系统还必须管理嵌入表的容量、放置位置及稀疏访问模式。这些技术将模型压缩(模型压缩)与分布式执行(模型训练)相结合,以维持较高的算术强度,并平衡大规模运行的成本。

相比之下,移动与边缘设备受到严格的功耗、散热和内存限制,因此必须进行软硬件协同设计。高效的网络架构(网络架构)与模型压缩(模型压缩)相结合,使模型能够部署于此类平台;与 H100 级加速器相比,参考移动设备的内存容量约缩小 10×,功耗范围约缩小 140×。当延迟、隐私、间歇性连接或出口带宽使集中式云端推理不可行时,边缘部署就是必需的。在这些条件下,效率决定的是可行性,而非小幅的成本优化。2

以 GPT-2/Llama 灯塔模型系列为例,自回归生成模型在词元生成期间对内存层次结构的边界施加压力。稠密自回归模型的小批量解码受内存带宽限制而停滞,因为每个词元步骤仅使用模型权重一次。增大批量可提高算术强度,而提示预填充则以计算受限的矩阵乘法方式执行。跨设备的模型划分——即张量并行与流水线并行(模型训练)的延伸——以集合通信为代价重新分配内存占用。推测解码(模型服务)通过在草稿模型上投入富余算力,突破目标模型的串行延迟瓶颈。这些机制共同展示了机器学习系统铁律如何适应复杂的工作负载结构。

在另一个极端,TinyML 与嵌入式系统——KWS/Wake Vision 灯塔模型所代表的领域——在千字节级 SRAM 预算、毫瓦级功耗范围以及多年运行生命周期内工作。在这些极端条件下运行,需要毫不妥协的系统工程规范:严格的性能剖析用于定位内存流量瓶颈,定制算子降层消除运行时开销,确定性执行则防止缓冲区溢出。历史上,严苛的资源限制催生了 MobileNets (Howard et al. 2017; Sandler et al. 2018) 和 EfficientNets (Tan and Le 2019) 等高效架构系列,证明了物理机器约束会主动推动算法创新。

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.
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.

一个相关前沿是物理 AI 与具身机器人,其中模型在闭环感觉运动控制周期内执行。在这种情境下,延迟预算(\(L_{\text{budget}}\))成为硬实时安全约束——尾延迟突增可能导致机械不稳定或碰撞——而持续的高带宽传感器数据流会在受限的设备端内存总线上,与模型权重流量直接竞争。

相同的物理界限适用于这些范式,而拟合的统计模型和 SLO 策略仍取决于具体部署。成功取决于核查这些差异并综合应用各项原则,而非追求孤立的优化。系统覆盖的部署情境越多,产生的潜在失效点也越多。因此,在下一个前沿,构成决定性约束的是鲁棒性,而不仅是覆盖范围。

构建鲁棒的 AI 系统

机器学习系统可能自信地给出错误响应,而常规可用性检查仍显示正常,且数周内都可能无人察觉。分布偏移可能在代码未变的情况下改变准确率,对抗性输入可以利用标准测试无法发现的漏洞,边缘案例则可能暴露仅靠调试无法修复的训练数据局限。这些是可信的生产风险,而不是某个单一散度指标必然预示的结果。

有限测试只能在存在不确定性的情况下估计系统在特定总体上的行为;它无法证明系统对未来每个输入都正确。漂移信号表明该总体何时可能发生变化,而带标签的结果则用于确定质量是否发生变化。二者共同说明,应将持续监控与回退策略、定期重新验证一道纳入设计要求,但这并不意味着每次分布偏移都会造成性能退化。运行层面的问题是:能否在失效影响扩散之前发现并诊断它。

因此,鲁棒性要求为平稳降级 进行设计,而不仅是预防失效。在单个系统尺度上,这种规范体现为回退路径、不确定性阈值、针对特定版本的回滚策略,以及监控钩子。回滚用于处理有问题的发布版本;对于外部漂移,则可能需要发出告警、减少流量、回退、收集数据,或在结果证据确认损害后重新训练。在更大尺度上,同样的逻辑延伸到硬件冗余和集成式多样性。随着 AI 系统在医疗、交通和金融领域承担越来越自主的角色,“在实验室有效”与“在现实中有效”之间的差距成为关键工程挑战。随着系统增加组件,鲁棒性变得更加重要,因为每个接口都会引入另一个需要监控的超时、过期输入、不一致状态或恢复路径。

以 AI 造福社会

在技术失效会造成公共后果的领域部署 AI,鲁棒的系统是先决条件。一个会不可预测地失效的医疗 AI,无法被托付患者照护任务。一个在负载下退化的教育系统,无法服务最需要它的学生。一个给出自信但未经校准的预测的气候模型,可能误导影响数百万人生活的政策决策。在每个领域,十三项原则都提供了共通的问题和界限,而领域证据则决定何种策略可以接受。

每个领域在实现社会价值之前,都面临不同的主导约束:

  • 科学发现:蛋白质折叠、药物相互作用建模和材料科学可能需要大量训练或推理吞吐量,其受机器学习系统铁律(原则 原则(英文原版))与硅契约(原则 原则(英文原版))支配;当工作采用分布式方式执行时,协调又增加了一项系统成本。
  • 医疗 AI:临床审查、经过校准的不确定性、外部验证和持续监控可能成为安全关键要求,因为基于一家医院人群训练的诊断模型,在部署到人口特征、疾病患病率或成像设备不同的另一家医院时,性能可能下降。
  • 个性化教育:在全球规模上保护用于个性化的敏感学生交互数据,会对数据治理和数据即代码原则(原则(英文原版))提出严格要求;交互式服务还必须满足其选定的延迟预算。

这三类应用都表明,仅有技术优化并不足够。数据—算法—机器分类体系、十三项定量原则和 Roofline 分析构成了系统工程的基础,但要将这一基础投入实际运行,还需要任何通用系统工具集都无法提供的领域专属验证。

正是这些应用具有明确边界,才使其系统约束易于分析和处理:医学诊断模型在预定义的标签集合内对病症进行分类,气候模型则在物理约束内预测气候统计量。下一个前沿要探究的是:同样的原则能否指导将工作委派给多个组件、同时保持端到端要求的系统。

以系统组合作为压力测试

对这些原则最具挑战性的压力测试,来自任务边界并非预先固定的系统。通用任务助手或多组件机器学习服务,可能将一个请求依次路由至检索、规划、工具执行、生成和验证环节。主导性挑战既在于算法设计,也在于系统工程:随着工作向各组件扇出,外围系统必须对延迟、可靠性、成本、安全性和可观测性施加界限。

系统组合 使多项核心原则同时发挥作用:

  • 机器学习系统铁律:随着工作向检索、规划、工具执行、生成和验证环节扇出,必须为每个组件执行的计算分配预算。
  • 硅契约:系统必须遵守 CPU、NVIDIA H100 级 GPU、张量处理单元和定制加速器各自的硬件约束。
  • 帕累托前沿:权衡面从准确率、延迟和内存等两三个指标,扩展为还涵盖安全性、公平性、事实准确性、隐私和成本的更大权衡面。
  • 统计漂移:漂移不仅适用于最终输出,也适用于检索到的文档、工具响应和中间决策。

组合系统不能依赖单一的模型质量声明;它需要行为可度量的接口,因为每个接口都是一个组件对另一个组件所作假设能够接受检验的地方 (Lampson 1983)。组合系统以单体结构的简单性换取显式协调。检索组件查找相关信息,推理组件处理这些信息,工具调用可能查询外部系统,验证器则检查输出。每个步骤都可以独立更新、监控和调试,但也都会引入另一项接口契约。这种分解以延迟和架构复杂性换取控制能力与可观测性,是帕累托权衡以及复杂性可能转移的一个例子,而非某种守恒定律。

Lampson, Butler W. 1983. “Hints for Computer System Design.” Proceedings of the Ninth ACM Symposium on Operating Systems Principles, 33–48. https://doi.org/10.1145/800217.806614.

系统成本在单个请求中就清晰可见。如果一个助手将工作扇出至检索器、规划器、两个工具、生成器和验证器,其实际延迟取决于该请求的关键路径;并行工具调用对延迟的贡献是其中的最大值而非总和,再加上编排开销。可靠性分析也必须考虑每个组件:每增加一个组件,就增加了一个需要监控的超时、模式不匹配、过期索引或验证器假阴性来源。传统微服务已经面临跨进程边界的运行时契约失效。组合式机器学习系统又增加了概率性接口,其中大语言模型规划器可能虚构工具名称,或生成偏离声明模式的 JSON,因此每个接口边界都需要防御性解析、重试逻辑和输出验证。增加系统结构可以增强能力,但这种结构必须遵守与任何生产级机器学习系统相同的延迟、可靠性和可观测性要求。

系统组合与基本系统工程原则直接一致。模块化子组件可以独立进行压缩(模型压缩),并在特定后端上加速(硬件加速)。每个组件都呈现出自身的硅契约(原则 原则(英文原版))和算术强度特征,为异构专门化开辟了途径。组件之间的接口建立了显式观测点,用于检测漂移、偏斜和数值退化。可靠地编排多个模型、在专用硬件之间动态路由请求,以及在共享内存状态之间强制保持事务一致性,都需要从数据摄取、加速器调度到运行反馈的端到端协同设计。

Systems Perspective 1.1: 新的黄金时代
Hennessy and Patterson (2019) 宣告了“计算机体系结构的新黄金时代”,其驱动力包括登纳德缩放定律的终结、摩尔定律的放缓,以及领域专用架构、开放指令集和敏捷芯片开发带来的新机遇。大规模 AI 工作负载是这些压力显现的领域之一。构建能力更强的 AI 服务,并非仅仅编写更好的损失函数;它将是一项系统工程挑战,涉及能源效率、高带宽互连、内存层次结构设计,以及能够让异构硬件有效工作而非闲置的软件栈。十三项原则提供了一套定量表述体系,帮助工程师应对这一环境,同时保持对物理界限与部署特定假设的区分。

Hennessy, John L., and David A. Patterson. 2019. “A New Golden Age for Computer Architecture.” Communications of the ACM 62 (2): 48–60. https://doi.org/10.1145/3282307.

这一时代要求具体的工程进步。实现百亿亿次级持续吞吐量 \((\geq 10^{18} \text{ FLOP/s})\) 并进一步超越,需要在供电、冷却、互连和软件协调方面采用新方法,而不仅仅是使用更快的芯片。这些分析工具使工程师能够应对这一环境,将系统从单节点加速器扩展到百亿亿次级集群。

前行之路

在这一规模上运行,需要围绕数据、算法和机器这三要素开展严谨的系统工程。通过血缘追踪和统计验证管理随机性数据,同时利用物理硬件限制和服务级别目标约束执行,可以在确定性软件与概率性机器学习之间架起桥梁。让隐藏假设接受度量,并将失效模式的观测深入至硬件接口,才能提供使学习型系统可靠所需的严谨性。

智能是系统的属性。 它源于数据流水线、模型架构、加速器硬件、运行时软件与运行治理的协同设计,而非任何孤立的算法突破。系统工程的核心教训并不是针对某个模型系列或某代硬件的固定配方,而是让隐藏依赖接受度量、依据物理硬件限制量化权衡,并要求生产部署对现实运行约束负责的工程规范。

工程责任

系统集成视角说明了为何伦理考量不能与物理和算法设计分离。硬件要求决定了使用门槛:如果一个模型在推理时需要一组高端数据中心加速器,就会将无力购置专用资本设备的组织排除在外。上游训练数据编码了历史采样偏斜,进而扭曲下游模型预测。加速器持续耗电直接影响设施散热和区域电网碳排放。从算术精度到数据整理,系统设计选择所分配的运行成本与社会后果,远远超出了工程团队的范围。

系统工程不仅要最大化原始能力,还要在社会与物理界限内负责任地运行部署系统。生产系统必须达到在易于获取的硬件上运行所需的算术效率,保持对硬件异常的容错能力,在严格的散热与功耗范围内运行,并在不同人口群体之间提供公平的统计准确率。实现全球气候监测和临床诊断助手等应用,需要严谨的系统工程规范,并将 负责任工程 中确立的治理准则作为首要物理与运行约束来指导实践。

这里确立的原则为单个机器学习系统提供了一致的分析视角。更大的系统并不会使这一视角失效;它们只是在不同边界上暴露了相同的约束。

前沿展望:从节点到机群

当工作负载超出单个节点的承载能力时,资源边界向外扩展,但瓶颈分析的推理方法保持不变。局部内存容量约束让位于对分带宽限制,局部异常处理扩展为机群级容错,而训练吞吐量则成为分布式协调问题。如页边阶梯图所示,在各 GPU 故障相互独立、具有相同恒定故障率,且任意 GPU 故障都会使整个资源池停止运行的模型下,对于一个包含 1,024 个 GPU 的资源池,即使尚未计入相关联的网络或电力中断,参考组件的平均失效前时间(MTTF)为 5.7 years,对应的集群平均故障间隔时间(MTBF)也会骤降至约 48.8 hours。持续数周的训练运行几乎必然遭遇节点故障。协同设计容错策略,将异步非阻塞检查点机制与局部状态恢复相结合,成为训练收敛的运行前提。在机群规模下,分析并未抛弃单节点原则,而是拓宽了这些原则的适用边界:识别起限制作用的约束,量化铁律中主导性的成本项,并追踪转移出去的延迟传播到了何处。本书在单机边界内阐明了这些约束,而机群规模的系统则将分析视角提升至更广泛的集群。当模型超出单设备内存容量时,规模扩展会引入新的分布式挑战:三维并行(数据并行、张量并行、流水线并行)、集合通信拓扑、数据中心调度,以及跨数千个互联加速器的弹性容错训练。

页边阶梯图,展示单个 GPU 约 5.7 年的平均失效前时间,与包含 1024 个 GPU 的资源池约 48.8 小时的平均故障间隔时间之间的对比。

机群规模使罕见的组件故障变成常态化的系统事件。

系统工程要求持续保持审慎质疑:孤立地优化组件往往会引入系统性故障模式,形成将局部基准测试优势转化为生产部署时常见的架构陷阱与认知谬误。

谬误与陷阱

机器学习系统中的谬误与陷阱有着共同根源:认为系统可以分解为彼此独立的部分。每一种谬误都假定,只需优化某一个维度、某一项指标或某一个阶段就足够了;每一种陷阱则展示了这一假设遭遇生产现实后的后果。

谬误:更好的工具和抽象会消除系统工程的复杂性。

工具通过抽象隐藏复杂性,但不会消除物理约束。隐藏内存管理的高级框架仍然会消耗内存。调优超参数的 AutoML 系统仍然面临帕累托前沿的限制。简化一个接口可能会将负担转移到另一个接口,不过良好的设计也能够消除偶然复杂性。相信工具可以消除根本约束的工程师,在这些约束随规模扩大而重新显现时会感到意外,而且它们的表现形式往往比原始问题更难诊断。

陷阱:优化一项指标,却不追踪转移出去的成本。

当某项优化使延迟降低 50% 时,应追问其他方面发生了什么变化。量化可能增加验证负担。缓存可能以占用内存容量为代价换取模型服务速度。有些简化能够消除偶然复杂性;另一些则只是转移成本。工程师如果只庆祝某项指标的改善,却不追踪这些影响,就可能构建出以意想不到的方式失效的系统。究竟属于哪一种情况,要由测量来判定。

谬误:掌握各个组件就等于掌握整个系统。

组件层面的专业知识是必要条件,但并非充分条件。如果工程师将数据流水线、训练、模型服务和运维理解为彼此孤立的领域,那么在面对数据模式变更沿训练流程级联传播、破坏量化假设,并引发生产环境中静默准确率下降的系统时,仍然会举步维艰。集成所产生的复杂性可能超出孤立观察各组件时所能发现的程度,因为接口会增加故障模式。系统思维意味着理解组件如何交互,而不仅仅是理解它们各自如何工作。

陷阱:扩大数据采集规模,却不衡量边际信息价值。

更多数据能够一致地改善模型质量这一假设,在实践中并不成立。如 数据选择 所示,一旦数据集实现了表征覆盖,收益递减就会出现:超过这一拐点后,数据集规模翻倍带来的准确率提升微乎其微,而存储、预处理和标注成本却会线性甚至超线性增长。数据引力原则(原则(英文原版))要求衡量下游运行成本,包括反复移动或扫描更大数据集的成本,是否超过将计算迁移至数据所在位置的成本。在未量化每个样本的边际信息价值时扩大数据量,优化的只是一个昂贵的代理指标。

谬误:单一准确率指标足以衡量模型质量。

仅依据总体准确率评估模型,会忽视实际运行条件。帕累托分析(原则 原则(英文原版))要求同时评估延迟、吞吐量、内存占用、能耗、公平性和模型服务成本。在尾延迟 SLO 为 100 ms 的条件下,准确率为 95%、执行耗时为 500 ms 的模型不可行,而准确率为 93%、在 50 ms 内完成执行的模型则满足生产要求。此外,汇总准确率往往会掩盖不同子群体之间严重的错误率差异(负责任工程)。全面评估应覆盖多维帕累托曲面,而非仅考察单一标量。

陷阱:将每一次漂移告警都视为自动回滚的触发条件。

统计漂移检测应触发经过诊断的响应,而非无条件自动回滚。当性能退化被追溯至存在缺陷的二进制程序或流水线部署时,回滚是适当的做法。然而,重新部署一个同样过时的旧检查点,并不能修复外部协变量漂移。安全的运行响应包括对金丝雀流量进行削减、采用回退启发式策略、隔离预测结果,或在真实标签确认性能退化后安排重新训练。运行监控必须将异常检测与针对具体原因的补救措施相结合(机器学习运维),依据已验证的故障机制进行干预,而非仅凭原始统计分布差异告警采取行动。

谬误:优化流水线中的单个阶段就能使整个系统变快。

阿姆达尔定律(原则 原则(英文原版))直接适用于端到端机器学习流水线。如果受 CPU 限制的预处理占端到端延迟的 90 percent,那么即使将加速器推理阶段加速至 10×,系统整体也只能获得 1.1× 的加速比。这类串行部分可能来自主机端图像增强、同步特征存储查询,或某些实现中仍受主机端限制的词元化。机器学习系统铁律(原则 原则(英文原版))将执行时间分解为数据移动、计算和延迟项,目的正是让工程师在投入优化工作之前识别主导项。严格的性能剖析能够明确执行时间实际消耗在何处(基准测试)。不做性能剖析就进行优化,无异于猜测;当干预针对非主导阶段时,阿姆达尔定律会严格限制加速比。

陷阱:只对看起来最容易优化的阶段进行性能剖析。

团队常常只对模型内核进行性能剖析,因为它直观可见、具备测量工具支持,并且由机器学习团队负责,而周边数据路径则分散在存储、预处理、网络和应用代码之中。这种局部视角可能使 10\(\times\) 的内核性能提升显得迫在眉睫,即使它几乎无法改变用户可感知路径的表现。端到端性能剖析能够确保优化目标符合实际:需要改进的是限制系统性能的阶段,而不是拥有最完善基准测试框架的阶段。

这些谬误与陷阱有着共同根源:试图将组件与运行它们的系统隔离开来。无论是优化单一指标、加速孤立阶段,还是在不考虑延迟约束的情况下评估准确率,只要忽视系统耦合,局部优化就会失效。跨越物理边界和运行边界进行推理,始终是机器学习系统工程的核心方法。

总结

机器学习系统工程通过跨越边界进行推理,区别于孤立的组件优化。十三项原则、复杂性守恒启发式和灯塔之旅框架,为将系统作为整体进行分析提供了工具。它们明确陈述的假设将精确界限与拟合模型、SLO 策略和设计启发式区分开来,使这些工具在框架、硬件代际和模型家族不断变化时仍然适用。

要点回顾: 跨越边界进行推理
  • 假设在不同实现中都至关重要:十三项原则结合物理界限、分解方法、拟合模型、要求和启发式,将依赖特定框架的实践技艺转化为可度量的推理。每项原则都只能在其声明的适用范围内使用。
  • 追踪转移的成本,而不预设成本守恒:压缩、批处理、监控和治理可能会在数据、算法和机器之间转移负担,而良好的设计能够直接消除偶然复杂性。测量可以区分这两种情况。
  • 边界揭示瓶颈:在批大小为一、使用两块 H100 的理想化模型中,生成一个 Llama 2 70B 词元所需的内存传输时间下界,约为按峰值计算性能得出的时间下界的 295.2×,而示例中的 p99 延迟为平均延迟的 40×。系统思维意味着测量物理条件、流量和用户要求在何处构成约束。
  • 规模改变起限制作用的项:下一个前沿是规模;在千 GPU 资源池中,组件以多年计的 MTTF 会转化为集群以天计的 MTBF。物理规律依旧,但约束转移到了机群层面。

Hennessy 和 Patterson 的 《计算机体系结构:量化研究方法》 为比较 CPI、时钟频率和指令数建立了共同的分析方法 (Hennessy and Patterson 2011; Hennessy and Patterson 2017)。这十三项原则为机器学习系统提供了相应的定量基础,但并不声称每一种诊断方法都是恒定不变的物理定律。它们为评估数据、算法和机器之间的权衡建立了共同的分析基准。

Hennessy, J. L., and D. A. Patterson. 2011. Computer Architecture: A Quantitative Approach. Morgan Kaufmann.
Hennessy, John L., and David A. Patterson. 2017. Computer Architecture: A Quantitative Approach. 6th ed. Morgan Kaufmann.
Sutton, Richard S. 2019. “The Bitter Lesson.” Incompleteideas.net 43.

长久有效的是这些原则所体现的思维立场:依据经验证据和物理界限进行推理,而非被动应对症状;量化权衡,而非追逐潮流;将系统设计视为约束优化。这是七十年计算研究所得出的苦涩的教训在工程层面的推论(引言):由于能够随计算规模扩展的通用方法一再超越人工精心设计的专门方法,持久优势属于能够承接这些计算的系统工程,而非任何单一的精巧架构 (Sutton 2019)。具体框架会兴起和衰落,硬件会代际更替,模型架构会被取代。对数据、计算和物理约束的严谨推理则不会过时。

在规模扩展的下一个前沿,一些模型已无法容纳于单台机器,机群中发生故障的概率变得很高,而网络链路也可能与本地内存总线一同成为限制因素。物理规律没有改变;改变的是它们构成约束的规模。

世界正竞相构建 AI 系统。我们的任务是以工程方法将其实现。

Vijay Janapa Reddi 教授,哈佛大学

Back to top

Footnotes

  1. 复杂度守恒启发式:特斯勒定律是一条设计格言,它指出,应用中不可约减的复杂度必须在用户、应用和平台之间的交互中由某个环节承担 (Tesler 1984);将其扩展到机器学习系统的所有复杂度是一种类比,而非物理定律。量化可能增加验证负担,抽象可能将实现细节移到接口背后,但良好的设计也可以直接消除偶然复杂度。大语言模型应用流水线展示了一种可能的转移:通过更短或更模糊的提示词简化面向用户的接口,可能会将工作转移到系统提示词、检索或输出验证中。应利用这一启发式寻找被转移的成本,而不是假定必然存在等量的补偿性成本。↩︎

  2. AI 普及化:通过高效的系统工程,让少数资源充裕的组织之外的群体也能使用 AI。面向移动设备优化的模型和云 API 可以扩大使用范围,但要可持续地实现这一目标,就需要在硬件、算法和基础设施各方面进行系统性优化,以在规模扩大时保持质量。↩︎

Tesler, Larry. 1984. The Law of Conservation of Complexity. Web page.
← 中文书架