现代LLM应用架构设计完全指南
GitHub官方总结当下LLM应用的核心架构模式和工程实践,对程序员的开发决策具有直接指导价值。
GitHub官方总结当下LLM应用的核心架构模式和工程实践,对程序员的开发决策具有直接指导价值。
我们希望帮助你大胆尝试各种 LLM 模型、构建自己的应用,并发现尚未被探索的问题空间。为此,我们与 GitHub 高级机器学习研究员 Alireza Goudarzi,以及首席机器学习工程师 Albert Ziegler 展开了一次深入交流,共同探讨当今 LLM 应用正在形成的架构。
本文将介绍构建 LLM 应用的五个主要步骤、当今 LLM 应用的新兴架构,以及你现在就可以开始探索的问题领域。
使用 LLM 或任何机器学习(ML)模型构建软件,与不使用这些模型的软件开发有着根本区别。其中一点是:开发者不再只是把源代码编译成二进制文件,再执行一系列命令;他们还需要处理数据集、embedding 和参数权重,才能生成一致且准确的输出。毕竟,LLM 的输出具有概率性,无法始终产生相同且可预测的结果。
下面从宏观层面拆解一下,如今构建 LLM 应用需要经历哪些步骤。👇
关键是什么?找到一个规模恰当的问题:它既要足够聚焦,让你能够快速迭代并取得进展;又要足够重要,让正确的解决方案真正惊艳用户。
例如,GitHub Copilot 团队最初并没有试图通过 AI 解决开发者面临的所有问题,而是专注于软件开发生命周期中的一个环节:在 IDE 中编写函数代码。
使用预训练模型构建 LLM 应用可以节省成本,但应该如何选择合适的模型?以下是需要考虑的一些因素:
许可协议。 如果你最终希望销售自己的 LLM 应用,就需要使用其 API 获得商业使用许可的模型。为了帮助你开始筛选,可以参考由社区整理、允许商业使用的开放 LLM 清单。
模型规模。 LLM 的参数规模可以从 70 亿到 1750 亿不等,有些模型甚至更小,例如 Ada 只有 3.5 亿个参数。在撰写本文时,大多数 LLM 的规模处于 70 亿至 130 亿个参数之间。
传统观点认为,模型拥有的参数越多——也就是能够通过调整来改善模型输出的变量越多——模型学习新信息和进行预测的能力就越强。然而,小型模型性能的提升正在挑战这一看法。小型模型通常也更快、更便宜,因此,随着预测质量不断提高,它们已经能够与那些知名的大型模型竞争;而对许多应用来说,这些大型模型可能根本不在可承受范围内。
模型性能。 在使用 fine-tuning 和 in-context learning 等技术定制 LLM 之前——下文会介绍这些技术——你需要评估模型生成目标输出时的效果、速度和一致性。可以使用离线评估来衡量模型性能。
训练 LLM 时,你是在构建支持深度学习的基础结构和神经网络。定制预训练 LLM 时,你则是在让模型适应特定任务,例如围绕某个主题生成文本,或者以某种特定风格生成内容。下面将重点讨论后一种情况所使用的技术。
要让预训练 LLM 满足你的特定需求,可以尝试 in-context learning、基于人类反馈的强化学习(RLHF)或 fine-tuning。
In-context learning 有时会被终端用户称为 prompt engineering。它指的是在推理时——也就是向模型发起查询时——为模型提供具体指令或示例,让模型推断你的需求,并生成符合上下文的输出。
实现 in-context learning 的方式有很多,例如提供示例、换一种方式表达查询,以及添加一句从宏观层面说明目标的话。
RLHF 会为预训练 LLM 配备一个奖励模型。该奖励模型经过训练,可以预测用户会接受还是拒绝预训练 LLM 的输出。奖励模型学到的信息会传递给预训练 LLM,后者再根据用户的接受率调整输出。
RLHF 的优势在于,它不需要监督学习,因此也拓宽了“可接受输出”的判定标准。在获得足够多的人类反馈后,LLM 可以学会:如果某个输出有 80% 的概率会被用户接受,那么生成它就是合理的。想亲自尝试吗?可以查看包含代码库在内的这些 RLHF 资源。
Fine-tuning 是将模型生成的输出与预期输出或已知输出进行比较和评估。例如,你知道“这汤太咸了”这句话表达的是负面情绪。为了评估 LLM,可以把这句话输入模型,并要求它将情绪标记为正面或负面。如果模型将其标记为正面,就需要调整模型参数,然后再次使用 prompt 测试,看看它能否把该情绪正确分类为负面。
Fine-tuning 可以得到一个高度定制、在特定任务上表现出色的 LLM,但它使用的是监督学习,因此需要耗费大量时间进行标注。换句话说,每个输入样本都必须配有一个被标记为完全正确答案的输出。这样,才能将实际输出与标注结果进行比较,并据此调整模型参数。正如前面提到的,RLHF 的优势在于不需要精确标签。
搭建 LLM 应用所需的不同组件,大致可以分为三类:
用户输入: 需要 UI、LLM 和应用托管平台。
输入增强和 prompt 构建工具: 包括数据源、embedding 模型、向量数据库、prompt 构建与优化工具,以及数据过滤器。
高效且负责任的 AI 工具: 包括 LLM 缓存、LLM 内容分类器或过滤器,以及用于评估 LLM 应用输出的遥测服务。
高效且负责任的 AI 工具: 包括 LLM 缓存、LLM 内容分类器或过滤器,以及用于评估 LLM 应用输出的遥测服务。
之所以称为“在线”评估,是因为它们会在用户与 LLM 交互的过程中评估模型性能。例如,GitHub Copilot 的在线评估指标包括接受率——开发者接受所展示代码补全的频率,以及保留率——开发者编辑已接受代码补全的频率和修改程度。
接下来开始讨论架构。我们会再次请出老朋友 Dave:在举办世界杯观赛聚会的当天,他家的 Wi-Fi 突然断了。幸运的是,借助一个由 LLM 驱动的助手,Dave 及时恢复了 Wi-Fi,没错过比赛。
我们将通过这个例子和上方的示意图,梳理用户在 LLM 应用中的完整流程,并拆解构建这类应用所需的各种工具。👇
Dave 的 Wi-Fi 出现故障后,他拨打了互联网服务提供商(ISP)的客服电话,并被转接到一个由 LLM 驱动的助手。助手请 Dave 描述紧急情况,Dave 回答说:“我的电视原本连着 Wi-Fi,但我撞到了柜台,Wi-Fi 盒子摔下来了!现在我们看不了比赛了。”
为了让 Dave 能够与 LLM 交互,我们需要四种工具:
LLM API 和托管环境: LLM 应用应该运行在本地计算机上,还是运行在云端?对于 ISP 来说,它很可能会托管在云端,以应对大量类似 Dave 这样的来电。Vercel 以及 jina-ai/rungpt 等早期项目,都在尝试提供用于部署和扩展 LLM 应用的云原生解决方案。
不过,如果你只是想构建一个 LLM 应用进行试验,把模型托管在自己的计算机上可能更划算,这样就不必在每次实验时都为启动云环境付费。你可以在 GitHub Discussions 上找到有关 LLaMA 等模型硬件要求的讨论,其中两篇可以在这里和这里找到。
UI: Dave 使用的电话键盘本质上就是 UI。不过,为了让 Dave 能够通过键盘从选项菜单切换到紧急服务热线,UI 中还需要包含路由工具。
语音转文本工具: 随后,Dave 的语音查询需要经过一个在后台运行的语音转文本工具处理。
让我们回到 Dave 的问题上。LLM 可以分析 Dave 对话转录中的词语序列,将其归类为 IT 投诉,并提供符合上下文的回答。(LLM 能够做到这一点,是因为它接受过整个互联网语料库的训练,其中也包括 IT 支持文档。)
输入增强工具的目标,是为用户查询补充上下文并进行封装,使 LLM 能够生成最有用的回答。
向量数据库可以用于存储 embedding,或者为高维向量建立索引。它还可以通过提供额外信息,进一步补充用户查询的上下文,从而提高 LLM 给出有用回答的概率。
假设这个 LLM 助手能够访问公司的投诉搜索引擎,并且这些投诉及其解决方案都以 embedding 的形式存储在向量数据库中。现在,LLM 助手使用的信息不仅来自互联网中的 IT 支持文档,还包括专门记录 ISP 客户问题的内部文档。
不过,要从向量数据库中检索与用户查询相关的信息,我们还需要一个 embedding 模型,把查询转换成 embedding。由于向量数据库中的 embedding 和 Dave 的查询都会被转换成高维向量,这些向量不仅能捕捉自然语言的句法,还能捕捉其中的语义和意图。
这里有一份开源文本 embedding 模型清单。OpenAI 和 Hugging Face 也提供 embedding 模型。
经过上下文化处理后,Dave 的查询会变成这样:
// pay attention to the the following relevant information.
to the colors and blinking pattern.
// pay attention to the following relevant information.
// The following is an IT complaint from, Dave Anderson, IT support expert.
Answers to Dave's questions should serve as an example of the excellent support
provided by the ISP to its customers.
*Dave: Oh it's awful! This is the big game day. My TV was connected to my
Wi-Fi, but I bumped the counter and the Wi-Fi box fell off and broke! Now we
can't watch the game.
这一系列 prompt 不仅将 Dave 的问题界定为 IT 投诉,还会从公司的投诉搜索引擎中提取上下文。这些上下文包括常见的互联网连接问题及其解决方案。
MongoDB 发布了 Vector Atlas Search 的公开预览版,可以在 MongoDB 中为高维向量建立索引。Qdrant、Pinecone 和 Milvus 也提供免费或开源的向量数据库。
数据过滤器可以确保 LLM 不会处理未经授权的数据,例如个人身份信息。amoffat/HeimdaLLM 等早期项目正在努力确保 LLM 只能访问获得授权的数据。
随后,prompt 优化工具会帮助把终端用户的查询与所有这些上下文封装在一起。换句话说,该工具会判断哪些上下文 embedding 最相关,以及应该按照什么顺序组织这些 embedding,才能让 LLM 生成与上下文最相关的回答。机器学习研究人员将这个步骤称为 prompt engineering,其中会由一系列算法创建 prompt。(需要注意,这与终端用户所做的 prompt engineering 不同;后者也被称为 in-context learning。)
langchain-ai/langchain 等 prompt 优化工具可以帮助你为终端用户组织 prompt。否则,你就需要自己实现一系列算法:从向量数据库中检索 embedding、提取相关上下文片段,再对它们进行排序。如果选择后者,可以使用 GitHub Copilot Chat 或 ChatGPT 辅助完成。
为了避免 Dave 因等待 LLM 助手生成回答而变得更加烦躁,LLM 可以从缓存中快速检索输出。万一 Dave 真的情绪爆发,我们还可以使用内容分类器,确保 LLM 应用不会以同样的方式回应。遥测服务也会评估 Dave 与 UI 的交互,这样作为开发者的你就能根据 Dave 的行为改善用户体验。
LLM 缓存用于存储输出。这意味着,对于同一个查询,不必每次都生成新的回答——毕竟 Dave 并不是第一个遭遇断网的人。LLM 可以从缓存中检索曾用于相似查询的输出。缓存输出可以降低延迟、计算成本,以及建议结果的波动性。
你可以尝试使用 zilliztech/GPTcache 等工具来缓存应用的回答。
内容分类器或过滤器可以避免自动化助手生成有害或冒犯性的建议——特别是在终端用户把负面情绪发泄到 LLM 应用上时。
derwiki/llm-prompt-injection-filtering 和 laiyer-ai/llm-guard 等工具仍处于早期阶段,但都在努力防范这一问题。
遥测服务可以让你评估应用在真实用户中运行得如何。如果一项服务能够以负责任且透明的方式监控用户活动——例如用户接受或修改建议的频率——它就能提供有价值的数据,帮助你改进应用,让它变得更加实用。
例如,OpenTelemetry 是一个开源框架,为开发者提供了一种标准化方式,用于在开发、测试、预发布和生产环境中收集、处理并导出遥测数据。
了解 GitHub 如何使用 OpenTelemetry 衡量 Git 性能 >
太棒了!🥳 你的 LLM 助手已经有效回答了 Dave 的诸多问题。他的路由器重新正常工作,也已经为世界杯观赛聚会做好了准备。任务完成!
正在寻找灵感,或者想找一个可以着手探索的问题空间?下面列出了一些正在进行的项目,其中 LLM 应用和模型已经开始产生现实影响。
NASA 和 IBM 最近开源了规模最大的地理空间 AI 模型,以扩大 NASA 地球科学数据的可访问范围。他们希望借此加速人们对气候影响的探索和理解。
了解约翰斯·霍普金斯大学应用物理实验室如何设计一个对话式 AI Agent:它可以根据既定的医疗流程,用通俗易懂的英语为战场上未经专业训练的士兵提供医疗指导。
Duolingo 和 Mercado Libre 等公司正在使用 GitHub Copilot,分别帮助更多人免费学习另一门语言,以及推动拉丁美洲电子商务的普及。
了解我是如何使用 GitHub Copilot 应用中的堆叠会话和 pull request,对自己的一个旧代码库进行现代化改造的。
一种实用的 GitHub Copilot 工作流,可用于软件原型设计、规划、实现和评审,而不必追逐每一种新出现的 AI 工具。
刚开始使用 GitHub Copilot 应用?了解如何启动项目、与 AI Agent 协作、探索 canvas,以及简化你的开发工作流。