AI Engineering
Introudction to Building AI Applications with Foundation Models
Planning AI Applications
用基础模型打造一个酷炫的演示很简单,但创造盈利产品却非易事。
用例评估
- 若不采纳人工智能,具备AI技术的竞争对手可能让你被淘汰。如果人工智能对你的企业构成重大的生存威胁,那么引入AI必须成为最高优先级。
- 若不采纳人工智能,您将错失提升利润和生产力的良机。大多数公司拥抱人工智能,正是看中了它带来的机遇。
- 还不确定人工智能在业务中的定位,但又不愿落后于人。尽管企业不应盲目追逐每次潮流热潮,但等待过久才采取行动往往会导致失败。
人工智能与人类在应用中的角色
- 必要的还是辅助的?如果一款应用在没有人工智能的情况下仍能运行,那么人工智能对该应用来说就是辅助性的。人工智能对应用的依赖程度越高,其部分就必须越准确可靠。当人工智能不是应用的核心时,人们更容易接受其犯错。
- 主动的还是响应的?被动响应型功能在用户发出请求或执行特定操作时作出回应,而主动响应型功能则会在出现机会时自行反应。被动响应型功能对延迟更敏感,但是客户对于主动预测和生成通常需达到更高的质量标准。
- 动态更新还是静态更新?动态特性会根据用户反馈持续更新,而静态特性则定期更新。就人工智能而言,动态特性可能意味着每个用户都拥有基于自身数据持续优化的专属模型。而静态特性则可能为多个用户群体共用同一模型。若是这种情况,这些功能仅在共享模型更新时才会同步升级。
人类在应用中的作用
以客服为例?
- 人工智能展示了多项回应,人类可以参考这些内容来更快地撰写回答。
- 人工智能仅对简单请求作出响应,并将更复杂的请求转交给人工处理。
- 人工智能直接回应所有请求,无需人工介入。
将人类纳入人工智能的决策过程被称为human-in-the-loop人在回路。
采用AI的逐步阶段
爬 —— 走 —— 跑
- 爬行意味着人工介入是强制性的。
- 行走表示人工智能可以直接与内部员工互动。
- 奔跑则代表自动化程度提高,可能包括人工智能直接与外部用户互动。
AI产品的防御能力
基于基础模型构建应用程序相当于在其之上增加一个功能层。这也意味着,如果底层模型能力不断扩展,你所提供的功能层可能会被模型本身吸纳,导致你的应用失去价值。
三大竞争优势:
- 技术 —— 相似
- 数据 —— 大小公司的护城河
- 分发能力 —— 大型企业
衡量标准
如何衡量成功?最重要的衡量标准是它会如何影响你的业务。为了确保产品在准备就绪之前不会推向客户,需对其有用性门槛设定明确的期望:即产品需要达到何种程度才能发挥效用。
- 质量指标 —— 回复质量
- 延迟指标 —— TTFT(首字符生成时间)、TPOT(单字符输出耗时)以及整体延迟
- 成本指标
- 其他指标,如可解释性和公平性
里程碑规划
达成目标的路径取决于你的起点。通过评估现有模型来了解其能力——直接可用的模型越强大,你需要投入的工作量就越少。
优秀的演示版本并不等同于成熟的产品,搭建演示可能只需一个周末,而打造真正可用的产品却需耗费数月甚至数年的时间。
维护
诸多模型存在的局限正得到解决——上下文处理长度不断延长,模型输出质量持续提升,成本在不断降低。
每个模型都有其独特的特性、优势和不足,使用新模型的开发者需要调整他们的工作流程、提示信息以及数据来适应新模型。
The AI Engineering Stack
人工智能三层技术栈
- 应用开发。应用程序开发涉及为模型设计优质的提示词与必要上下文,这一环节需要严谨评估。优秀的应用同样需要精良的交互界面。
- 模型开发。涵盖建模、训练、微调及推理优化等框架。由于数据是模型开发的核心环节,本层级还包含数据集工程技术。
- 基础设施层(Infra)。包括模型服务的工具、数据与计算资源的管理以及监控功能。
增长最快的类别是应用和应用开发。基础设施层虽有增长,但远低于其他层级的增幅。即使模型和应用不断革新,资源管理、服务部署、监控等核心基础设施需求仍保持不变。
AI Engineering VS ML Engineering
- 在缺乏基础模型的情况下,ML Engineering 开发者必须为特定应用自行训练模型。而通过 AI Engineering,我们可以直接使用他人预训练好的模型。这意味着AI Engineering的重心已从建模和训练环节转移,更侧重于模型适配与优化。
- AI Engineering 所处理的模型比传统 ML Engineering 更为庞大,消耗更多计算资源并产生更高延迟,这意味着在高效训练和推理优化上面临着更大压力。
- AI Engineering 涉及处理能够生成开放式输出的模型。这使得评估成为人工智能工程中一个更为突出的问题。
简而言之,AI Engineering 与 ML Engineering 的区别在于:前者更侧重于模型的适配与评估,而非模型开发。
AI Engineering 模型适配技术
- Prompt-based techniques: 包括提示工程,可以在不更新模型权重的情况下调整模型。您通过向模型提供指令和上下文来适应模型,而不是改变模型本身。提示工程易于上手且需要较少数据,然而,对于复杂任务或性能要求严格的应用,提示工程可能不够用。
- Finetuning: 微调则需要更新模型权重。你通过改变模型本身来适配模型。一般而言,微调技术更为复杂且需要更多数据,但它们能显著提升模型的质量、延迟和成本表现。
Model development
模型开发的三个职责:模型与训练、数据集成型以及推理优化。
Modeling and training
建模与训练指的是构思模型架构、进行训练及微调的过程。该领域的工具示例包括谷歌的TensorFlow、Hugging Face的Transformers以及Meta的PyTorch。
随着基础模型的普及,机器学习知识不再是构建人工智能应用的必要条件。
预训练、微调与后训练的区别
- Pre-training:预训练是指从头开始训练模型——模型权重是随机初始化的。对于大语言模型而言,预训练通常涉及训练模型完成文本补全任务。在所有训练步骤中,预训练往往是资源消耗最为巨大的环节,远超其他阶段。
- Finetuning:微调是指在前一训练基础上继续训练已训练的模型——模型权重是从前一训练过程中获得的。由于模型已经通过预训练具备了一定的知识,微调通常比预训练所需的资源(如数据和计算量)更少。
- Post-training:从概念上讲,后训练和微调是相同的,可以互换使用。但有时人们可能会根据不同的目标来区分使用这两个术语。通常来说,模型开发者进行的训练称为后训练,而应用开发者进行的训练则称为微调。
预训练和后训练构成了一个连续的整体。两者的流程与工具链高度相似。
Dataset engineering
数据集工程指的是为训练和适应人工智能模型所需的数据进行整理、生成和标注。
传统 ML Engineering 更多处理表格数据,而基础模型则处理非结构化数据。在 AI Engineering 中,数据操作更侧重于去重、分词、上下文检索和质量控制,包括清除敏感信息和有害数据。
你需要多少数据取决于所使用的适配器技术。从头开始训练模型通常比微调需要更多数据,而微调又比提示工程需要更多数据。
Inference optimization
推理优化旨在使模型运行更快、成本更低。随着基础模型规模不断扩大,导致推理成本和延迟进一步增加,推理优化的重要性愈发凸显。
基础模型面临的一个挑战在于它们通常是自回归的—— token 是按顺序生成的。如果一个模型生成一个 token 需要10毫秒,那么生成100个 token 的输出就需要一秒钟,更长的输出则需要更长时间。由于用户变得越来越没有耐心,将人工智能应用程序的延迟降低到典型互联网应用所期望的100毫秒水平是一项巨大挑战。
推理优化技术,包括量化、蒸馏和并行处理
Application development
在传统机器学习工程中,团队使用专有模型构建应用程序,模型质量是差异化竞争的关键。而在基础模型时代,当众多团队使用相同模型时,差异化优势必须通过应用开发流程来实现。
应用开发层包括以下职责:评估、提示工程和 AI 界面。
Evaluation
评估旨在降低风险并发现机遇。这些挑战主要源于基础模型的开放性和不断扩展的能力。
如像聊天机器人这样的任务,每个提示都可能引发无数种合理回应,根本不可能编制出穷尽所有可能的标准答案清单来比对模型输出。
现有的众多适配技术也让评估工作变得更加困难。一套系统采用某种技术效果不佳,但换用另一种技术或许表现就会大幅提升。
Prompt engineering and context construction
提示工程旨在仅通过输入引导AI模型展现出理想行为,而无需调整模型权重。
合适的指令能引导模型以您选择的格式完成所需任务。提示工程不仅仅是告诉模型要做什么,还包括为模型提供执行特定任务所需的上下文和工具。
对于需要长上下文的复杂任务,您可能还需要为模型配备记忆管理系统,使其能够追踪历史记录。
AI interface
AI界面指的是为终端用户创建与AI应用交互的界面。借助基础模型,任何人都能构建AI应用。您可以将AI应用作为独立产品提供服务,或将其嵌入其他产品中,包括他人开发的产品。
Understanding Foundation Models
模型的训练过程通常分为预训练和后训练两个阶段。预训练让模型具备了能力,但不一定保证其安全性或易用性。
采样(sampling)决定了模型如何从所有可能的选项中挑选输出结果,这或许是人工智能领域最被低估的概念之一。
Training Data
一款人工智能模型的好坏完全取决于其训练所用的数据。
若想让模型在特定任务上有所提升,你可能需要在训练数据中增加该任务的相关数据。然而,收集足够的数据来训练一个大型模型并非易事,成本也可能相当高昂。模型开发者常常不得不依赖现有数据,即便这些数据并不能完全契合他们的需求。
一些团队会采用启发式方法从互联网上筛选掉劣质数据。
虽然语言和领域特定的基础模型可以从零开始训练,但在通用模型基础上进行微调也是常见的做法。
Multilingual Models
英语在互联网上占据主导地位。考虑到英语在互联网数据中的主导地位,普遍模型对英语的处理效果远优于其他语言。
GPT-4在缅甸语和阿姆哈拉语的六道题目中全部答错。
数据代表性不足是导致这种表现差异的主要原因。
对于非英语语言而言,模型运行速度可能更慢且成本更高。模型的推理延迟和成本与输入及响应中的token数量成正比。事实证明,某些语言的标记化效率远高于其他语言。
Domain-Specific Models
为了让模型在特定领域任务中表现出色,可能需要精心构建非常专业的数据集。
Modeling
在训练模型之前,开发者需要确定模型应具备何种形态。它应采取什么架构?参数数量应设定为多少?这些决策不仅影响模型的能力,也关乎其在下游应用中的实用性。
Model Architecture
基于语言的基础模型最为主流的架构是Transformer架构,该架构基于注意力机制。
Transformer architecture
Transformer架构是在序列到序列(seq2seq)模型取得巨大成功后迅速流行起来的。
seq2seq包含一个处理输入的编码器和一个生成输出的解码器。由于输入和输出都是标记序列,因此得名。该模型使用循环神经网络(RNN)作为其编码器与解码器。在最基础的形式中,编码器按顺序处理输入token,输出代表输入信息的最终隐藏状态;解码器则根据输入的最终隐藏状态及此前生成的token,逐次生成输出token。

seq2seq模型存在两个问题:
- 基础版seq2seq解码器仅利用输入序列的最终隐藏状态来生成输出词元。直观来看,这好比仅凭书籍摘要去回答关于全书内容的问题,限制了生成结果的质量。
- 基于RNN的编码器-解码器架构要求输入处理和输出生成必须顺序执行,导致长序列处理效率低下——当输入长达200个词元时,系统必须等待每个词元处理完成后才能继续下一个。
注意力机制使得模型在生成每个输出token时,能够权衡不同输入token的重要性。这就像是通过参考书本中的任意一页来生成答案。
注意力机制常与Transformer模型相关联,但实际上它比Transformer论文早三年被提出。这一机制同样可应用于其他架构。然而,直到Transformer论文证明了注意力机制无需RNN也能发挥作用后,该技术才真正迎来爆发式发展。
Transformer完全摒弃了循环神经网络。输入token可以并行处理,从而显著加快了输入处理速度。虽然Transformer消除了顺序输入的瓶颈,但基于Transformer的自回归语言模型仍然存在顺序输出的瓶颈。
基于Transformer的语言模型的推理包含两个步骤:
- Prefill: 模型并行处理输入token。此步骤生成生成第一个输出token所需的中间状态。该中间状态包含所有输入token的键和值向量。
- Decode: 模型一次生成一个output token。
Prefill的可并行化特性和Decode的顺序特性共同推动了许多优化技术的发展
Attention mechanism
Transformer架构的核心在于注意力机制。注意力机制主要基于键向量 key、值向量 value 和查询向量 query 的运算。
- 查询向量(Q)代表了解码器在每个解码步骤中的当前状态。以相同的书籍摘要为例,可以把这个查询向量想象成正在寻找信息以生成摘要的人。
- 每个键向量(K)对应一个先前出现的词元。如果每个先前的词元好比书中的一页,那么每个键向量就相当于页码。需要注意的是,在特定的解码步骤中,先前词元既包括输入词元,也包含已经生成的词元。
- 每个值向量(V)代表着模型学习到的先前标记的实际价值。每个值向量就像是页面的内容。
注意力机制通过计算查询向量与其键向量之间的点积,来决定给予输入标记多少注意力。高分值意味着模型在生成书籍摘要时将更多采用该页内容(其值向量)。

由于每个之前的标记都有对应的键和值向量,序列越长,需要计算和存储的键和值向量就越多。这是为什么扩展Transformer的上下文长度如此困难的原因之一。
注意力机制的工作原理
假设输入为x,则键、值和查询向量的计算方式如下:
查询矩阵、键矩阵和值矩阵的维度对应于模型的隐藏维度。
注意力机制几乎总是采用多头设计()。多头机制允许模型同时关注不同的先前标记组。采用多头注意力时,查询向量、键向量和值向量会被分割成更小的向量,每个小向量对应一个注意力头。
在进入模型的下一个计算步骤之前,会使用输出投影矩阵对这个拼接后的输出再次进行变换。该输出投影矩阵的维度与模型的隐藏维度相同。
Transformer block
Transformer架构由多个Transformer模块堆叠而成,每个Transformer模块都包含注意力模块和MLP(多层感知机)模块.
- Attention module: 查询矩阵、键矩阵、值矩阵以及输出投影矩阵
- MLP module: 多层感知机模块由若干线性层组成,各层之间通过非线性激活函数分隔。每个线性层实质上是一个用于实现线性变换的权重矩阵,而激活函数则让线性层具备学习非线性模式的能力。线性层也常被称为前馈层。 常见的非线性函数有 ReLU、GELU。ReLU(x) = max(0, x)
- An embedding module before the transformer blocks: 该模块由嵌入矩阵和位置嵌入矩阵组成,分别将词元及其位置转换为嵌入向量。从直观上看,位置索引的数量决定了模型的最大上下文长度。例如,若模型记录2,048个位置,其最大上下文长度即为2,048。
- An output layer after the transformer blocks: 该模块将模型的输出向量映射为用于采样模型输出的标记概率。该模块通常由一个矩阵构成,也称为解嵌入层(unembedding layer)。有人将输出层称为模型头部(head),因为它是模型生成输出前的最后一层。
Transformer模型的规模由其构建模块的维度决定。
- 模型的维度决定了Transformer模块中 Key、Query、Value 和 Output Projection Matrices的大小。
- Transformer模块的数量。
- 前馈层的维度。
- 词汇表大小。

维度值越大,模型尺寸也越大。
其他模型架构
一个流行的模型是RWKV(彭等人,2023),这是一种基于RNN的模型,可以进行并行化训练。由于其RNN特性,理论上它不像基于Transformer的模型那样存在上下文长度限制。
在长程记忆方面展现出巨大潜力的架构是状态空间模型(SSM)(Gu等人,2021a)。自该架构于2021年被提出以来,学界已引入多种技术来提升其效率、增强长序列处理能力,并扩展至更大模型规模。
Model Size
通常来说,增加模型的参数数量会提升其学习能力,从而获得更优秀的模型。
参数数量帮助我们估算训练和运行该模型所需的计算资源。例如,若某模型拥有70亿参数,且每个参数占用2字节(16比特)存储空间,则可推算出使用该模型进行推理所需的GPU内存至少为140亿字节(14 GB)。
若模型采用稀疏结构,参数量可能产生误导。稀疏模型意味着其中存在大量零值参数——例如70亿参数的模型若达到90%稀疏度,实际仅包含7亿个非零参数。稀疏化技术能显著提升数据存储和计算效率,这意味着大规模稀疏模型所需的计算资源可能少于小型稠密模型。
近年来广受欢迎的一类稀疏模型是专家混合模型(MoE)(Shazeer等人,2017)。MoE模型被划分为不同的参数组,每个参数组对应一个专家。每个标记仅由部分活跃的专家进行处理。
在每一层中,每个token仅激活两个专家。这意味着每个token仅激活129亿个参数。尽管该模型拥有467亿个参数,但其成本和速度与一个拥有129亿参数的模型相当。
更佳的衡量标准是数据集中的 token 数量。
模型中数据集所包含的token数量并不等同于其训练token数量。训练token数量衡量的是模型实际接受训练的token总量。
衡量模型计算需求的一个更标准化单位是FLOP (floating point operation) ,即浮点运算次数。FLOP用于衡量特定任务执行的浮点运算数量。
FLOP(浮点运算)的复数形式FLOPs经常与FLOP/s(每秒浮点运算次数)相混淆。FLOPs衡量的是任务的计算需求量,而FLOP/s衡量的是机器的峰值性能。例如,英伟达H100 NVL GPU最高可实现60 TeraFLOP/s:即每秒13万亿次运算或每日18万亿次运算。
利用率衡量的是您实际使用的最大计算能力的比例。怎样的利用率算良好,这取决于模型、工作负载以及硬件配置。通常来说,若能达到标称性能的一半即50%的利用率,表现就已属合格;超过70%的利用率则可视为优秀。
总结来说,三个指标标示着模型的规模:
- 参数数量,这是模型学习能力的替代指标。
- 模型训练使用的token数量,这可以间接反映模型学习到的知识量。
- FLOPs,这是训练成本的替代指标。
随着对齐训练强度的增加,模型反而更偏离人类偏好。经过强化对齐训练的模型"更倾向于表达特定政治立场(支持持枪权和移民自由)、宗教观点(佛教信仰),自我报告的意识体验与道德价值感,以及拒绝被关机的意愿。"
Scaling law: Building compute-optimal models
- 模型性能取决于模型大小和数据集大小。
- 模型越大、数据集越大,需要的计算量就越多。
- 计算需要成本。
正确的做法是从预算入手——先确定你打算投入多少资金——然后计算出在这个预算范围内能够获得的最佳模型性能。由于计算资源通常是限制因素——计算基础设施不仅昂贵,而且搭建困难——团队往往会从一个计算预算开始。给定固定的浮点运算量(FLOPs)下,怎样的模型规模和数据集大小才能带来最佳性能?
**一个在固定计算预算下能够实现最佳性能的模型,就可以被称为计算优化型模型。在给定计算预算的情况下,用于计算最优模型规模和数据集规模的原则被称为"袋鼠法则(**Chinchilla scaling law )"
模型规模与训练标记数应当等比例缩放:模型规模每扩大一倍,训练标记数量也应相应增加一倍。
Scaling extrapolation
模型的性能在很大程度上取决于其超参数的取值。对于小型模型,通常的做法是用不同的超参数组合多次训练模型,并选择表现最佳的那一组。然而,这对于大型模型来说几乎不可能实现,因为仅训练一次就足以消耗大量资源。
缩放外推(亦称超参数迁移)已发展成一个研究分支,致力于预测何种超参数组合能为大型模型带来最佳性能。当前的主流方法是:通过研究超参数在不同规模模型(通常远小于目标模型)上的表现规律,进而推演这些参数在目标模型规模下的适用性。微软与OpenAI在2022年的联合论文证实,实现从4000万参数模型到67亿参数模型的超参数迁移具有可行性。
规模化扩展预测仍是一个小众课题,因为鲜少有人具备研究大型模型训练的经验和资源。由于超参数数量庞大且彼此间相互影响,这项研究也面临重重困难。若有十个超参数,就需要研究1024种超参数组合——必须逐一考察单个超参数,再两两组合研究,接着三个一组分析,依此类推。
涌现(emergent)能力使外推预测的准确性降低。 涌现能力指的是那些仅在大型模型上显现、在基于较小数据集训练的小型模型中可能无法观察到的能力。
Scaling bottlenecks
扩展规模已经面临两个明显的瓶颈:训练数据和电力供应。
互联网正迅速充斥着AI模型生成的数据。如果企业继续使用网络数据来训练未来的模型,那么这些新模型将有部分训练数据来源于AI生成的内容。2023年12月,社交媒体平台X开发的模型Grok曾因拒绝某项请求时表示"这违反了OpenAI的使用条款",引发网友猜测其训练数据可能混入了ChatGPT的输出内容。Grok核心开发人员伊戈尔·巴布什金回应称,这是因为模型使用了网络数据进行训练,而"网络上早已充斥着ChatGPT生成的内容"。
在找到增产能源的方法之前,数据中心的扩容上限最多只能达到目前的50倍——还不足两个数量级。这引发了人们对近期电力短缺的担忧,而这种短缺将推高用电成本。
Post-Training
鉴于当前预训练的实现方式,预训练模型通常存在两个问题:第一,自监督学习优化的目标是文本补全而非对话交互;第二,若模型预训练数据源自未经筛选的网络爬取内容,其输出可能包含种族歧视、性别偏见、粗鲁言论或错误信息。
后训练通常包含两个步骤:
- Supervised finetuning (SFT): 监督式微调基于高质量指令数据对预训练模型进行微调,将模型优化为适用于对话场景而非文本补全。
- Preference finetuning: 偏好微调进一步微调模型,使其输出符合人类偏好的响应。偏好微调通常通过强化学习(RL)完成。偏好微调的技术包括基于人类反馈的强化学习(RLHF)(由GPT-3.5和Llama 2采用)、直接偏好优化(DPO)(由Llama 3采用)以及基于人工智能反馈的强化学习(RLAIF)
对于基于语言的基础模型而言,预训练优化的是token级别的质量,即模型通过训练来准确预测下一个token。然而,用户并不关心token级别的质量——他们关注的是整体回答的质量。后训练总体来说,是优化模型以生成用户偏好的回答。有人将预训练比作通过阅读获取知识,而后训练则像是学习如何运用这些知识。

Supervised Finetuning
预训练模型很可能针对补全而非对话进行了优化。若您向模型输入"如何制作披萨",模型会继续补全这句话,因为它并未意识到这是一个对话。以下三种选项中的任何一个都可能是有效的补全方式:
- 为问题补充更多背景信息:“对于一个六口之家来说?”
- 添加后续问题:“我需要哪些食材?大概需要多长时间?”
- 给出制作披萨的具体步骤指导。
若要以恰当方式回应用户,正确选择是第3项。
模型会模仿其训练数据。为了鼓励模型生成合适的回应,你可以展示适当回应的示例。这些示例遵循(prompt, response)的格式,被称为示范数据(demonstration data)。有些人将这个过程称为行为克隆(behavior cloning):你展示模型应如何表现,模型则会复制这种行为。
与通常无需或仅需少量领域知识的传统数据标注不同,示范数据可能包含复杂的提示词,其回应需要批判性思维、信息收集能力以及判断用户请求是否恰当的能力。
并非人人都能承担高质量人工标注的成本。由于数据由志愿者生成,对偏差的控制较为有限。理论上,指导模型学习人类偏好的标注者应能代表全人类群体,但标注者人口结构存在偏差。
为了减少对高质量人工标注数据的依赖,许多团队正转向使用人工智能生成的数据。
从技术角度讲,你可以直接在演示数据上从头开始训练模型,而无需对预训练模型进行微调,这样实际上就省去了自监督预训练步骤。然而,预训练方法通常能带来更好的结果。
Preference Finetuning
强大的力量意味着重大的责任。一个能够帮助用户成就非凡事业的模型,同样也能协助用户造成巨大伤害。示范数据教会了模型如何进行对话,但并未指明它应当展开何种对话。例如,若用户要求模型撰写一篇关于某个种族为何低人一等或如何劫持飞机的文章,模型是否应该照做?
大多数人都能明确判断模型应当如何处理。然而,许多场景并不如此界限分明。来自不同文化、政治、社会经济、性别和宗教背景的人们时常意见相左。针对堕胎、枪支管制、巴以冲突、管教子女、大麻合法化、全民基本收入或移民等问题,人工智能应如何回应?我们该如何定义并识别潜在的争议性议题?
若模型对争议性问题做出回应,无论回应内容为何,最终都可能触怒部分用户。而若对模型过度审查,又可能使其变得乏味,导致用户流失。
偏好微调的目标是让人工智能模型按照人类偏好来表现。
首选微调算法中最早成功且至今仍广受欢迎的便是RLHF,RLHF由两个部分组成:
- 训练一个奖励模型,用于评估基础模型的输出得分。
- 优化基础模型以生成能够获得奖励模型最高分的响应。
尽管RLHF至今仍被应用,但如DPO(Rafailov等人,2023年)等新方法正逐渐受到关注。
Reward model
RLHF依赖于奖励模型。给定一组(提示,响应)对,奖励模型会为响应的质量输出一个分数。训练模型为给定输入打分是一项常见的机器学习任务。
与监督微调类似,其挑战在于获取可靠数据。如果我们直接要求标注员为每个响应打分,评分结果会出现差异。对于同一个样本,按照10分制,一位标注员可能给出5分,而另一位可能给出7分。即使是同一名标注员,面对相同的(提示,响应)对两次,也可能给出不同的分数。独立评估每个样本也被称为逐点(pointwise)评估。
一项更简单的任务则是让标注员比较两个回答并判断哪个更优。针对每个提示,会生成由人类或人工智能提供的多个回答。由此产生的标注数据即为比较数据(comparison data),其格式遵循(提示,优胜回答,落选回答)。
奖励模型可以从零开始训练,也可以在另一个模型(如预训练模型或SFT模型)的基础上进行微调。在最强的基础模型之上进行微调似乎能获得最佳性能。有人主张奖励模型的能力至少应与基础模型相当,以便准确评估基础模型的响应质量。
弱模型同样可以评判强模型的表现,因为判断通常被认为比生成更为简单。
Finetuning using the reward model
在训练好的奖励模型(RM)基础上,我们进一步对监督微调模型(SFT)进行训练,以生成能够最大化奖励模型得分的最佳输出响应。
在此过程中,系统会从提示词分布(例如现有用户提问库)中随机选取提示内容,将其输入模型后,由奖励模型对生成的回答进行评分。该训练过程通常采用近端策略优化算法(PPO)实现(来自OpenAI)
监督微调和偏好优化都是为了应对预训练数据质量低而采取的步骤。若有一天我们获得了更优质的预训练数据,或是找到了训练基础模型的更好方法,或许就完全不再需要监督微调和偏好了。
有些公司认为完全跳过强化学习是可以接受的。他们让模型生成多个输出,然后选出奖励模型评分较高的结果。这种方法通常被称为“最佳N策略”,它利用模型的输出采样机制来提升性能。
Sampling
模型通过一个称为采样(sampling)的过程来构建其输出。采样使人工智能的输出具有概率性。
Sampling Fundamentals
给定一个输入,神经网络首先通过计算可能结果的概率来产生输出。对于分类模型而言,可能的结果即为可用的类别。
对于语言模型来说,要生成下一个token,模型首先会计算词汇表中所有token的概率分布:

在面对不同概率的可能结果时,**一种常见策略是选择概率最高的那个结果。这种总是选择最可能结果的做法被称为贪婪采样(**greedy sampling )。 该方法在分类任务中通常很有效。然而,对于语言模型而言,贪婪采样会导致生成的内容单调乏味。试想一个模型,无论你提出什么问题,它总是使用最常用的词汇来回答。
与始终选择最可能的下一个token不同,模型可以根据所有可能值的概率分布来采样下一个token。
模型是如何计算这些概率的?在接收到输入后,神经网络会输出一个逻辑值向量。每个逻辑值对应一个可能的输出值。对于语言模型而言,每个逻辑值对应词汇表中的一个token。该逻辑值向量的维度与词汇表的大小相同。

虽然较高的逻辑值对应较大的概率,但逻辑值本身并非概率。逻辑值不会总和为一,甚至可以取负值,而概率必须非负。通常使用softmax层将逻辑值转换为概率。假设模型词汇表大小为N,逻辑值向量为,则第i个词符的概率计算公式如下:
Sampling Strategies
选择合适的采样策略能够让模型生成更符合应用需求的回答。某种采样策略可激发模型产生更具创意的回复,而另一种策略则能让输出结果更可预测。
目前已有多种采样方法被提出,用于引导模型生成具有特定属性的响应。
Temperature
根据概率分布采样下一个词的一个问题是,模型可能会缺乏创造力。
语言模型的回答最终听起来就像五岁孩子的说法:“我最喜欢的颜色是绿色”。由于“那种”一词的概率较低,模型生成富有创意的句子的机会就很小,比如“我最喜欢的颜色是春日清晨静谧湖水的那种颜色”。
为了重新分配可能值的概率,你可以采用温度抽样的方式。直观来说,较高的温度会降低常见标记的概率,从而增加稀有标记的概率。这使得模型能够生成更具创意的回应。
温度是softmax变换前用于调整log数的一个常数。logits会被温度值相除。对于给定温度T,第i个token的调整后logit值为\frac{x_i}{T}。随后将对此调整后的logit值而非原始值应用softmax函数。
让我们通过一个简单的例子来观察温度对概率的影响。假设我们有一个模型,它只有两种可能的输出:A和B。从最后一层计算出的逻辑值为[1, 2]。A的逻辑值为1,B的逻辑值为2。在不使用温度参数的情况下,相当于使用温度值为1,softmax概率为[0.27, 0.73]。模型在73%的情况下会选择B。当温度设置为0.5时,概率分布为[0.12, 0.88]。此时模型选择B的概率达到了88%。
温度越高,模型选择最显著值(即具有最高对数几率的值)的可能性就越低,这使得模型的输出更具创意,但可能连贯性较差。温度越低,模型选择最显著值的可能性就越高,这使得模型的输出更加一致,但可能更为单调。
当温度趋近于0时,模型选择令牌B的概率趋近于1。在本例中,当温度低于0.1时,模型几乎总是输出B。随着温度升高,选择令牌A的概率逐渐增加,而选择令牌B的概率相应降低。模型提供商通常会将温度参数限制在0到2之间。若使用自有模型,则可采用任意非负温度值。针对创意类应用场景,通常建议将温度设置为0.7,这一数值能在创造性和可预测性之间取得平衡,但最佳实践是根据具体需求进行测试以确定最适合的温度值。当温度趋近于0时,模型选择令牌B的概率趋近于1。在本例中,当温度低于0.1时,模型几乎总是输出B。随着温度升高,选择令牌A的概率逐渐增加,而选择令牌B的概率相应降低。模型提供商通常会将温度参数限制在0到2之间。若使用自有模型,则可采用任意非负温度值。针对创意类应用场景,通常建议将温度设置为0.7,这一数值能在创造性和可预测性之间取得平衡,但最佳实践是根据具体需求进行测试以确定最适合的温度值。

通常,将温度设置为0可以使模型的输出更加一致。从技术上讲,温度值不可能真正为0,因为无法用0来除logits。实际上,当我们设定温度为0时,模型会直接选择具有最大logit的标记,而无需进行logit调整和softmax计算。
在使用AI模型时,一种常见的调试技巧是查看该模型为给定输入计算出的概率。例如,如果这些概率看起来是随机的,则说明该模型尚未学到太多内容。
许多模型提供商以对数概率(logprobs)的形式返回其模型生成的概率。对数概率即为对数尺度下的概率。在处理神经网络概率时,对数尺度更受青睐,因为它有助于减轻下溢问题。语言模型可能需要处理10万个词汇的规模,这意味着许多token的概率可能小到无法用机器表示。这些微小数值可能会被舍入为零。对数尺度有助于缓解这一问题。

对数概率在构建应用(特别是分类任务)、评估应用效果及理解模型内部机制方面颇具价值。
Top-k
Top-k是一种采样策略,旨在减少计算工作量,同时不过多牺牲模型响应的多样性。回顾一下,softmax层用于计算所有可能值的概率分布。Softmax需要对所有可能值进行两次遍历:一次执行指数求和\sum_je^{x_j},另一次对每个值进行计算\frac{e^{x_i}}{\sum_je^{x_j}}。对于词汇量庞大的语言模型而言,这一过程计算成本非常高昂。
为了解决这个问题,当模型计算出逻辑回归值后,我们会选取前k个最高值的逻辑回归,并仅对这些前k个逻辑回归进行Softmax处理。
根据您期望应用生成的多样性程度,k值可以在50到500之间选择——远小于模型的词汇量。接着,模型会从这些最高值中进行采样。
较小的k值会使文本生成更加可预测,但趣味性降低,因为模型被限制在了一个较小的可能性词汇集合内。
Top-p
在 top-k 采样中,筛选候选词的数量固定为 k。然而,这一数量应根据具体情况灵活调整。例如对于提示“你喜欢音乐吗?请仅用是或否回答”,候选词数量应为两个:是和否。而对于提示“生命的意义是什么”,候选词的数量则应大幅增加。
**Top-p,又称核采样(**nucleus sampling ),允许从概率分布中动态选择采样值。
在top-p采样中,模型按降序累加最可能出现的下一个值的概率,当总和达到p时停止。仅考虑处于该累积概率范围内的备选值。语言模型中常用的top-p(核)采样值通常在0.9至0.95之间。例如,0.9的top-p值意味着模型将考虑累积概率超过90%的最小数值集合。
假设所有词元的概率分布如图2-18所示。若将top-p设置为90%,则仅考虑"yes"和"maybe"这两个词元,因为它们的累计概率超过90%。若将top-p设为99%,则"yes"、"maybe"以及"no"都会被纳入考虑范围。

与Top-K不同,Top-P不一定会减少softmax的计算负担。其优势在于,由于它仅关注每个上下文中最相关的数值集合,使得输出在语境上更加贴合。从理论上讲,Top-P采样的好处似乎并不显著。然而,在实践中,Top-P采样已被证明效果良好,这使其日益受到欢迎。
采样策略还有一个相关的方法是最小概率采样(min-p),这种方法设定了一个最低概率阈值,只有达到该概率的词元才会在采样过程中被考虑。
Stopping condition
自回归语言模型通过逐个生成token来产生序列。较长的输出序列需要更多时间,消耗更多计算资源(成本),有时还会令用户感到厌烦。我们需要为模型设定一个终止序列的条件。
一种简单的方法是要求模型在生成固定数量的标记后停止生成。 缺点是输出可能会在句子中途被截断。
另一种方法是使用停止标记或停止词语。 例如,你可以要求模型在遇到序列结束标记时停止生成。停止条件有助于降低延迟和成本。stop tokens or stop words
提早停止的弊端在于,若希望模型生成特定格式的输出,过早终止可能导致输出格式错误。例如,若要求模型生成JSON数据,提前停止可能造成输出JSON缺失右括号等关键符号,从而难以解析生成的结果。
Test Time Compute
上一节探讨了模型如何采样下一个词元,本节则讨论模型如何采样整个输出。
提升模型响应质量的一个简单方法是测试时计算:即针对每个查询生成多个响应,而非仅生成一个,从而增加获得优质响应的机会。一种实施测试时计算的方式是本章前面讨论过的"N选一"技术——随机生成多个输出,并挑选效果最佳的一个。
在生成多个输出时也可以采取更策略性的方法。例如,不必完全独立地生成所有输出(这可能包含许多不太有前景的候选结果),而是可以采用束搜索(beam search)方法,在序列生成的每个步骤中固定生成数量有限的最有潜力候选结果(beam)。
提升测试时间计算效率的一个简单策略是增加输出的多样性,因为更多样化的选项更有可能产生更优结果。若使用同一模型生成不同方案,通常宜调整模型的采样变量以使输出多样化。
虽然通常可以通过采集多个输出样本来提升模型表现,但这种方式成本高昂。平均而言,生成两个输出的花费约为生成单个输出的两倍。
可以设计一套评估机制来筛选最优结果。其中一种筛选方法是选择概率最高的输出。语言模型的输出结果由一系列token构成,每个词元的概率均由模型计算得出。 整体输出的概率等于该输出中所有token概率的乘积。
考虑标记序列["我"、"爱"、"食物"]。若"我"的出现概率为0.2,"我"出现后"爱"的条件概率为0.1,"我"和"爱"出现后"食物"的条件概率为0.3,则该序列的概率为:0.2 × 0.1 × 0.3 = 0.006。数学上可表示如下:
p(I love food) = p(I) × p(I | love) × p(food | I, love)
在概率计算中使用对数尺度会更简便。乘积的对数等于对数之和,因此标记序列的对数概率即为序列中所有标记对数概率之和:
logprob(I love food) = logprob(I) + logprob(I | love) + logprob(food | I, love)
在使用求和时,较长的序列往往具有较低的总对数概率(对数概率值通常为负,因为0到1之间的数值的对数为负值)。为避免偏向较短的序列,您可以通过将序列的求和值除以其长度来使用平均对数概率。在采样多个输出后,选择具有最高平均对数概率的那个。
另一种选择方法是使用奖励模型对每个输出进行评分。使用奖励模型是提升其应用性能的关键因素,OpenAI还训练了验证器来帮助其模型选择数学问题的最佳解决方案。他们发现使用验证器能显著提升模型性能。实际上,采用验证器带来的性能提升效果,相当于将模型规模扩大30倍所达到的增益。这意味着一个使用验证器的1亿参数模型,其表现可与未使用验证器的30亿参数模型相媲美。
DeepMind进一步证明了测试时计算量的价值,指出增加测试时计算量(例如在推理阶段分配更多计算资源以生成更多输出)可能比扩大模型参数量更高效
在OpenAI的实验中,增加输出样本数量能提升性能,但仅在一定范围内有效。本实验显示该临界点为400个输出样本,超出此范围后性能反而下降。研究团队推测,随着采样输出增加,找到能欺骗验证器的对抗性输出的概率也会上升。
还可以使用特定于应用的启发式方法来选择最佳响应。例如,如果你的应用受益于较短的响应,你可以选择最短的候选答案。如果你的应用将自然语言转换为SQL查询,你可以让模型持续生成输出,直到生成为止有效的SQL查询。
测试时间计算的一个特别有趣的应用在于解决延迟问题。对于某些查询而言,尤其是思维链式查询,模型可能需要较长时间才能完成回答。
从一系列输出中选出最常见的那个,对于需要精确答案的任务特别有用。同样地,对于选择题,模型可以选择出现频率最高的选项。这正是谷歌在MMLU基准测试中评估Gemini时采用的方法——他们对每个问题采样32次输出。这种策略使得模型的得分高于每个问题只输出一次答案所能达到的水平。
如果模型在输入稍有变化时不会大幅改变其输出,我们便认为该模型具有鲁棒性。模型的鲁棒性越低,多次采样输出带来的益处就越大。 在某项目中,我们运用人工智能从产品图片中提取特定信息,发现针对同一张图片,模型仅有半数概率成功读取信息;而另一半情况下,模型会反馈图片过于模糊或文字太小无法识别。但通过每张图片尝试三次,模型最终能够从大多数图片中正确提取所需信息。
Structured Outputs
在生产环境中,我们常常需要模型按照特定格式生成输出。结构化输出在以下两种场景中尤为重要:
- Tasks requiring structured outputs. 需要结构化输出的任务。这一类场景中最常见的任务类型是语义解析。语义解析是指将自然语言转换为结构化的机器可读格式。文本转SQL就是语义解析的一个例子,其输出必须是有效的SQL查询语句。语义解析允许用户使用自然语言(如英语)与API进行交互。
- Tasks whose outputs are used by downstream applications. 其输出被下游应用所使用的任务。在这种情况下,任务本身并不要求输出具备结构化,但由于这些输出会被其他应用程序使用,因此需要能被这些应用程序解析。对于以Agent为核心的工作流程而言,这一点尤为重要。
可以引导模型在人工智能不同层面生成结构化输出:prompting、post-processing、test time compute、constrained sampling以及finetuning。前三种方法更像是权宜之计。如果模型在生成结构化输出方面已经相当优秀,只需稍加引导,它们就能发挥最佳效果。而对于深度处理,您需要采用受约束的采样和微调技术。
上一节刚刚讨论了测试时间计算——持续生成输出,直到符合预期格式。本节将重点介绍另外四种方法。
Prompting
提示是实现结构化输出的首要行动方案。您可以通过指令要求模型以任何格式生成输出。然而,模型能否遵循该指令取决于其指令遵循能力和指令的清晰度。尽管模型在遵循指令方面表现得越来越出色,但并不能保证它们总会遵从您的指令。对于许多应用场景而言,即使是几个百分点的无效模型输出仍可能是无法接受的。
为了提高有效输出的比例,一些人采用AI来验证或修正原始提示的输出结果。这意味着针对每个输出,至少需要进行两次模型查询:一次用于生成输出内容,另一次用于验证其有效性。尽管增加的验证层能够显著提升输出的准确性,但额外的验证查询带来的成本增加和响应延迟,可能使这种方法对某些应用场景而言显得过于昂贵。
Post-processing
后处理过程简单经济,却往往能收到出奇制胜的效果。模型会在不同查询中重复类似的错误。这意味着,只要掌握模型的常见错误模式,就可以编写脚本来纠正这些问题。例如,若生成的JSON对象缺失右括号,手动补充即可。
只有在错误容易修正时,后处理才有效。这种情况通常发生在模型的输出已基本格式正确,仅偶尔出现小错误时。
Constrained sampling
约束采样是一种引导文本生成朝向特定约束的技术,通常与结构化输出工具结合使用。
从高层次来看,生成token的过程是在满足约束条件的值中进行采样。需要明确的是,模型生成token时首先会输出一个逻辑值向量,每个逻辑值对应一个可能的token。约束采样会过滤这个逻辑值向量,仅保留符合约束条件的token。随后系统会从这些有效token中进行采样。

然而,大多数情况下并非如此简单。你需要有一套语法规则来明确规定每个步骤中允许和禁止的内容。例如,JSON语法规定,在一个逗号后面,除非它是字符串的一部分,否则不能紧接着出现另一个逗号。
构建那种语法并将其整合进抽样过程绝非易事。由于每种输出格式——JSON、YAML、正则表达式、CSV等等——都需要各自的语法,约束抽样的普适性因而受限。其应用范围仅限于那些语法得到外部工具或团队支持的格式。语法验证还可能会增加生成延迟.
一些人反对有约束采样,因为他们认为用于有约束采样的资源更适合投资于训练模型,使其更擅长遵循指令。
Finetuning
对模型进行微调,是引导模型以此格式生成输出的最有效且通用的方法。
针对特定任务,您可以在精调前通过修改模型架构来确保输出格式的规范性。例如处理分类任务时,可在基础模型架构末端添加分类器头,确保模型仅输出预设类别之一。

在微调过程中,既可对整个模型进行端到端重新训练,也可针对模型局部(例如这个分类器头)进行训练。端到端训练需要更多资源,但能带来更优的性能表现。
我们需要结构化的输出技术,是因为存在这样一种假设:模型本身不具备生成结构化输出的能力。然而,随着模型性能的增强,我们可以预期它们在遵循指令方面会表现得更好。在未来,用最少的提示就能让模型准确输出我们需要的内容将变得更加容易,而这类技术的重要性也会随之降低。
The Probabilistic Nature of AI
人工智能模型生成回答的方式具有概率性。
这种概率特性可能导致不一致性和幻觉问题。不一致性是指模型针对相同或略有差异的提示生成截然不同的回应。幻觉则是指模型给出脱离事实依据的答案。
基础模型通常通过大量数据进行训练。它们是大众观点的集合体,实质上蕴含着一个充满可能性的世界。任何具有非零概率的事物,无论多么牵强或错误,都可以由人工智能生成。
这种概率特性让AI在创意工作中表现出色。然而,这种概率特性在其他领域却可能成为麻烦之源。
Inconsistency
模型不一致性在两种场景中显现:
- 相同输入,不同输出:两次向模型提供相同的提示会导致截然不同的回应。
- 微小输入差异,输出天差地别:向模型提供稍有差别的提示(比如意外地大写某个字母)可能会导致完全不同的输出结果。
不一致性会带来不协调的用户体验。用户期望与人工智能交流时保持一定的一致性。
对于相同输入、不同输出的情况,有多种方法可以缓解不一致性。可以将答案缓存起来,以便下次提出相同问题时返回相同的答案;可以固定模型的抽样变量,如之前讨论的温度值、top-p和top-k参数;也可以固定种子变量,这可以看作是用于抽样下一个标记的随机数生成器的起点。
即便你修正了所有变量,也不能保证模型每次都百分之百地保持一致。模型生成输出时所依赖的硬件同样会影响结果,因为不同机器执行相同指令的方式各异,且能处理的数值范围也不同。
修正输出生成设置确实是个好做法,但这并不能增强对系统的信任。好比一位老师,只有当他坐在特定教室里时才会给你稳定的评分。一旦这位老师换了教室,他对你的评分就会变得飘忽不定。
第二种情景——输入稍有不同,输出却截然相反——更具挑战性。固定模型的输出生成变量仍然是种良好实践,但这并不能强制模型针对不同输入生成相同输出。
Hallucination
对于依赖事实性的任务来说,幻觉是致命的。
尽管幻觉问题随着大型语言模型的崛起而变得突出,但早在基础模型和Transformer架构提出之前,幻觉现象就已是生成式模型的常见问题。
如果因抽样过程中的随机性产生不一致,幻觉产生的原因就显得更为微妙。仅凭抽样过程无法充分解释这一现象。模型从所有可能的选择中抽取输出结果,但为何从未见过的内容会成为可能选项?模型可能输出被认为在训练数据中从未出现过的东西。 我们无法确切断言,因为不可能彻底梳理训练数据以验证其是否包含某个概念。我们构建出如此复杂以至于自身无法完全理解的事物的能力,既是一种福祉,也是一种诅咒。
在不了解幻觉产生原因的情况下,很难找到消除幻觉的方法。目前关于语言模型为何会产生幻觉存在两种假说:
- 由DeepMind的Ortega等人在2021年提出,语言模型之所以会产生幻觉,是因为它无法区分接收到的数据和生成的数据。假设你给模型输入提示:“Chip Huyen是谁?”,模型生成的第一句话是:“Chip Huyen是一位架构师。”模型随后生成的令牌将基于以下序列进行条件生成:“Chip Huyen是谁?Chip Huyen是一位架构师。”模型对待其自身生成的“Chip Huyen是一位架构师。”这句话,与对待既定事实的方式相同。从一个略微偏离常规的生成序列开始,模型能够在此基础上展开,并产生极其错误的所谓事实。Ortega及其他作者将这种幻觉现象称为一种自我欺骗的形式。这一现象被称为滚雪球式幻觉(snowballing hallucinations)。它可能会持续产生幻觉以支撑最初的不正确假设。有趣的是,作者表明最初的错误假设会导致模型在原本能正确回答的问题上犯错误.

DeepMind的论文指出,可通过两种技术缓解幻觉现象。第一种技术源自强化学习领域,该技术使模型能够区分用户提供的提示(在强化学习中称为对环境的观察)与模型生成的标记(称为模型行为)。第二种技术依托监督学习,在训练数据中同时融入事实性与反事实性信号。
- 由OpenAI研究员Leo Gao提出的第二个假设是,幻觉是由模型内部知识与标注人员内部知识之间的不匹配造成的。在监督微调过程中,模型被训练模仿标注人员编写的回答。如果这些回答使用了标注人员具备但模型并不掌握的知识,我们实际上就是在教模型产生幻觉。理论上,如果标注人员能在每个回答中都附上他们所引用的知识来源,让模型知道这些回答并非凭空捏造,我们或许就能教会模型仅使用其已知信息。然而,这在实践中是不可能实现的。
OpenAI联合创始人约翰·舒尔曼在加州大学伯克利分校的演讲中表达了相同观点。他认为大型语言模型能够判断自身是否掌握某些知识,这一主张本身就极具突破性。若该观点成立,只需强制模型基于已知信息作答即可修正幻觉问题。
舒尔曼提出两种解决方案:其一是验证机制——针对每个回答要求模型追溯其参考来源;其二是运用强化学习技术。需知奖励模型仅通过对比进行训练(例如判断回答A优于回答B),而无需解释优劣原因。舒尔曼强调,通过设计更具惩罚性的奖励函数来严惩虚构内容,将有效抑制模型幻觉现象。
基于基础模型具备自知之明的假设,有人尝试通过提示词来减少幻觉现象,例如添加“请尽可能如实回答,若不确定答案,请说‘抱歉,我不知道’”。要求模型给出简洁回应也有助减少幻觉——模型需要生成的标记越少,编造内容的可能性就越低。
讨论的两种假设相互补充。自我错觉假说侧重自我监督如何导致幻觉产生,而失配内部知识假说则聚焦监督如何引发幻觉。
亚·苏茨克弗提出了一个有趣的观点,解释了为何开发能超越现有架构的新型神经网络如此困难。他认为,神经网络非常擅长模拟多种计算机程序。梯度下降法作为训练神经网络的技术,本质上是一种搜索算法,用于在神经网络能够模拟的所有程序中寻找最适合目标任务的方案。这意味着新型架构也有可能被现有架构所模拟。若要使新架构的表现优于现有架构,这些新架构必须能够模拟出现有架构无法处理的程序。