TowardsDataScience 2023 博客中文翻译(三百零三)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

适者生存:紧凑型生成式 AI 模型是规模化成本效益 AI 的未来

原文:towardsdatascience.com/survival-of-the-fittest-compact-generative-ai-models-are-the-future-for-cost-effective-ai-at-scale-6bbdc138f618?source=collection_archive---------6-----------------------#2023-07-25

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:Adobe Stock。

支持灵活、针对性强的检索式模型作为规模化部署生成式 AI 应用的最佳解决方案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Gadi Singer

·

关注 发表在 Towards Data Science ·18 分钟阅读·2023 年 7 月 25 日

在人工智能 (AI) 模型复杂性和计算能力快速增长了十年之后,2023 年标志着对效率和生成 AI (GenAI) 广泛应用的关注转变。因此,一批参数少于 150 亿的新型模型被称为灵活 AI,可以在特定领域中接近 ChatGPT 风格的大型模型(参数超过 1000 亿)的能力。尽管 GenAI 已经在各行业广泛应用于各种商业用途,但紧凑且智能的模型使用率正在上升。在不久的将来,我预计将会有少量的大型模型和大量的小型、更灵活的 AI 模型嵌入到无数应用中。

尽管较大的模型取得了巨大进展,但在训练和环境成本方面,大型模型未必更好。TrendForce 估计,仅 GPT-4 的 ChatGPT 训练费用就超过 1 亿美元,而灵活模型的预训练成本则低得多(例如,MosaicML 的 MPT-7B 的预训练费用约为 20 万美元)。大部分计算成本发生在持续的推断执行过程中,但这与大型模型面临的类似挑战有关,包括高昂的计算费用。此外,托管在第三方环境中的大型模型会带来安全性和隐私问题。灵活模型的运行成本大大降低,并提供了额外的好处,如适应性、硬件灵活性、在更大应用中的集成性、安全性和隐私、可解释性等(见图 1)。对较小模型表现不如大型模型的看法也在改变。较小的、针对性的模型并不缺乏智能——它们可以在商业、消费和科学领域提供等效或更优的性能,增加了其价值,同时减少了时间和成本投资。

越来越多的这些灵活模型大致匹配了 ChatGPT-3.5 级别的大型模型的性能,并且在性能和范围上持续快速提升。而且,当灵活模型配备了即时检索策划的特定领域私人数据和基于查询的网络内容有针对性的检索时,它们比记忆广泛数据集的大型模型更加准确且更具成本效益。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1. 灵活 GenAI 模型的好处。图片来源:Intel Labs。

随着灵活的开源 GenAI 模型不断推进领域的快速发展,这一“iPhone 时刻”——当一种革命性技术变得主流——正受到“Android 革命”的挑战,因为一个强大的研究和开发社区在彼此的开源努力基础上进行构建,创造出越来越强大的灵活模型。

思考、执行、了解:目标领域的灵活模型可以像巨型模型一样表现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2. 生成型人工智能能力分类。图像来源:Intel Labs。

要更深入地了解何时以及如何让较小的模型在生成型人工智能中提供高度竞争的结果,重要的是观察到,无论是灵活的还是巨型的生成型人工智能模型,都需要三类能力才能表现出色:

  1. 认知能力以思考: 包括语言理解、总结、推理、规划、从经验中学习、长篇阐述和互动对话。

  2. 功能技能以执行: 例如——在自然环境中阅读文本、阅读图表/图形、视觉识别、编程(编码和调试)、图像生成和语音。

  3. 信息(记忆或检索)以了解: 网页内容,包括社交媒体、新闻、研究和其他一般内容,和/或策划的领域特定内容,如医学、金融和企业数据。

思考的认知能力。 基于其认知能力,模型可以“思考”并理解、总结、综合、推理和构建语言及其他符号表示。无论是灵活模型还是巨型模型,在这些认知任务中表现良好,并且这些核心能力是否需要庞大的模型规模尚不清楚。例如,像微软研究的 Orca这样的灵活模型已经在多个基准测试中展示了与 ChatGPT 相匹配或超越的理解、逻辑和推理技能。此外,Orca 还表明,推理技能可以从作为教师的大型模型中提炼出来。然而,目前用于评估模型认知技能的基准仍然很初级。需要进一步的研究和基准测试来验证灵活模型是否可以通过预训练或微调来完全匹配巨型模型的“思考”能力。

执行功能技能。 较大的模型由于其作为全能模型的一般关注,可能具有更多的功能技能和信息。然而,对于大多数业务用途来说,每个应用程序所需的功能技能有特定的范围。用于业务应用的模型应具备灵活性和扩展性,但通常不需要无限的功能技能。GPT-4 可以生成多种语言的文本、代码和图像,但说几百种语言并不一定意味着这些巨型模型本质上具有更多的认知能力——它主要是给模型增加了更多的“执行”功能技能。此外,功能专用引擎将与 GenAI 模型关联,并在需要该功能时使用——例如,将数学“Wolfram 超能力”添加到 ChatGPT 模块化可以提供最佳的功能,而不会给模型带来不必要的规模负担。例如,GPT-4 正在部署插件,这些插件实质上利用了较小的模型来提供附加功能。此外,据传 GPT-4 模型本身是由多个巨型(少于 100B 参数)“专家混合”模型组成,这些模型在不同的数据和任务分布上进行训练,而不是像 GPT-3.5 那样的单一密集模型。为了获得最佳的能力和模型效率组合,未来的多功能模型可能会使用每个小于 15B 参数的更小、更专注的专家混合模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3. 基于检索的功能扩展模型可以提供广泛的功能和相关信息,与模型大小基本无关。图片来源:Intel Labs。

需要了解的信息(记忆的或检索的)。 巨型模型通过在参数记忆中记忆大量数据来“知道”更多内容,但这不一定使它们更聪明。它们只是比小模型更具一般知识。在零-shot 环境下,巨型模型具有较高的价值,对于新用例提供了通用消费者基础,当不需要进行目标定位时,以及在提炼和微调灵活模型(如 Orca)时作为教师模型。然而,目标明确的灵活模型可以为特定领域进行训练和/或微调,从而提供所需能力的更锐利技能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4. 检索在允许小模型匹配更大模型的价值(使用 Contriever 检索方法)。图片来源:Intel Labs,基于 Mallen et al的工作。

例如,一个针对编程的模型可以专注于与医疗 AI 系统不同的能力集。此外,通过使用针对内部和外部数据的检索,模型的准确性和时效性可以大大提高。最近的一项研究 显示,在PopQA 基准上,参数只有 1.3B 的模型通过检索可以与参数高达 175B 的模型表现相当(见图 4)。在这种意义上,具有高质量索引的可访问数据的针对性系统的相关知识可能远比全能的通用系统更广泛。这对于需要用例或应用程序特定数据的多数企业应用程序来说可能更为重要——在许多情况下,还需要本地知识而不是广泛的通用知识。这就是灵活模型未来将显现其价值的地方。

三大因素推动灵活模型的爆炸性增长

评估灵活模型的好处和价值时需要考虑三个方面:

  1. 中等模型尺寸的高效率。

  2. 开源或专有的许可。

  3. 模型的专门化包括通用或针对性检索。

在尺寸方面,灵活的通用模型,如Meta 的 LLaMA-7B 和 -13B技术创新研究所的 Falcon 7B 开源模型,以及专有模型如MosaicML 的 MPT-7B微软研究院的 Orca-13BSalesforce AI Research 的 XGen-7B 正在迅速改进(见图 6)。选择高性能的小型模型对操作成本以及计算环境的选择有重大影响。ChatGPT 的 175B 参数模型和 GPT-4 的估计 1.8 万亿参数 需要大量的加速器安装,如具有足够计算能力的 GPU 以处理训练和微调工作负载。相比之下,灵活的模型通常可以在任何选择的硬件上运行推理,从单插槽 CPU,到入门级 GPU,再到最大加速机架。灵活 AI 的定义目前已基于 13B 参数或更小模型的出色结果经验性地设定为 15B 参数。总体而言,灵活模型提供了一种更具成本效益和可扩展性的方法来处理新的用例(见灵活模型的优缺点部分)。

开源许可的第二个方面允许大学和公司互相迭代模型,从而推动了创造性创新的蓬勃发展。开源模型允许小型模型能力的惊人进步,如图 5 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5. 灵活的开源非商业和商业 GenAI 模型在 2023 年上半年迅速崛起。图片来源:英特尔实验室。

从 2023 年初开始,有多个例子显示了通用灵活生成性 AI 模型的出现,比如Meta 的 LLaMA,该模型包括 7B、13B、33B 和 65B 参数。以下在 7B 和 13B 参数范围内的模型是通过微调 LLaMA 创建的:斯坦福大学的Alpaca,伯克利人工智能研究所的Koala,以及由加州大学伯克利分校、卡内基梅隆大学、斯坦福大学、加州大学圣地亚哥分校和 MBZUAI 的研究人员创建的Vicuna。最近,微软研究院发布了一篇关于尚未发布的 Orca 的论文,这是一个基于 LLaMA 的 13B 参数模型,模拟了大型模型的推理过程,并在针对特定领域进行微调之前取得了令人印象深刻的结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6. 使用 Vicuna 评估集,通过 GPT-4 评估的开源聊天机器人的相对响应质量比较。图片来源: 微软研究院

Vicuna 可以作为近期从 LLaMA 衍生出的开源灵活模型的一个良好代表。Vicuna-13B 是一个由大学合作创建的聊天机器人,旨在“解决现有模型如 ChatGPT 中训练和架构细节的缺乏。”在 ShareGPT 上进行用户共享对话微调后,Vicuna 的响应质量相比于 ChatGPT 和 Google Bard 的 GPT-4 判定结果超过 90%。然而,这些早期的开源模型尚不可用于商业用途。MosaicML 的 MPT-7B技术创新研究所的 Falcon 7B为商业可用的开源模型,其质量 reportedly 与 LLaMA-7B 相当。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 7. Orca-13B 在 BIG-bench Hard 的复杂零样本推理任务上表现与 ChatGPT 相当。图片来源: 微软研究院

Orca 在复杂的零-shot 推理基准测试中,如Big-Bench Hard(BBH),超越了传统的指令调优模型,如 Vicuna-13B,超过了 100%。在 BBH 基准测试中,它与 ChatGPT-3.5 达到了相同的水平,”根据研究人员的说法。Orca-13B 在其他通用模型中的顶级表现强化了这样的观点,即巨型模型的巨大规模可能来源于早期模型的暴力破解。巨型基础模型的规模对一些较小的模型,如 Orca-13B,用于提炼知识和方法可能很重要,但大小不一定是推理所必需的——即使对于一般情况也是如此。需要注意的是——对模型的认知能力、功能技能和知识记忆的全面评估,只有在广泛部署和应用时才有可能。

截至撰写本博客时,Meta 发布了他们的 Llama 2 模型,包含 7B、13B 和 70B 参数。该模型在首代发布四个月后问世,提供了显著的改进。在对比图表中,灵活的 Llama 2 13B 达到了与前一代 LLaMA 更大模型以及 MPT-30B 和 Falcon 40B 相似的结果。Llama 2 是开源的,可用于研究和商业用途。它在与微软及包括英特尔在内的多个合作伙伴的紧密合作下推出。Meta 对开源模型的承诺及其广泛的合作将无疑为我们看到的这种模型的跨行业/学术快速改进周期提供额外的推动力。

灵活模型的第三个方面涉及专业化。许多新推出的灵活模型都是通用的——例如 LLaMA、Vicuna 和 Orca。通用灵活模型可能完全依赖于它们的参数记忆,通过细调方法进行低成本更新,包括LoRA: 大型语言模型的低秩适应以及检索增强生成,在推理时实时从策划的语料库中提取相关知识。检索增强的解决方案正在建立并不断通过 GenAI 框架如LangChainHaystack进行增强。这些框架允许轻松灵活的集成索引和有效访问大型语料库以进行基于语义的检索。

大多数商业用户更倾向于针对其特定领域的定制模型。这些针对性模型通常也是基于检索的,以利用所有关键的信息资产。例如,医疗保健用户可能希望自动化患者沟通。

针对性模型使用两种方法:

  1. 对模型本身进行专业化以满足目标使用案例所需的任务和数据类型。这可以通过多种方式实现,包括在特定领域知识上对模型进行预训练(如phi-1在来自网络的教科书质量数据上进行预训练)、对相同规模的通用基础模型进行微调(如Clinical Camel微调了 LLaMA-13B),或将巨型模型的知识提炼并学习到学生型灵活模型中(如Orca学习模仿 GPT-4 的推理过程,包括解释痕迹、逐步思维过程和其他复杂指令)。

  2. 为即时检索策划和索引相关数据,这可能是大量的,但仍在目标使用案例的范围/空间内。模型可以检索持续更新的公共网络和私有消费者或企业内容。用户确定索引哪些来源,从而选择来自网络的高质量资源以及更完整的资源,如个人的私人数据或公司的企业数据。虽然检索现在已集成到巨型和灵活系统中,但在小型模型中发挥着关键作用,因为它提供了模型性能所需的所有必要信息。它还允许企业将其所有私有和本地信息提供给在其计算环境中运行的灵活模型。

灵活生成性 AI 模型的优点和缺点

在未来,紧凑模型的规模可能会增加到 20B 或 25B 参数,但仍远低于 100B 参数范围。也有许多中等规模的模型,如 MPT-30B、Falcon 40B 和 Llama 2 70B。虽然这些模型在零样本任务上预计表现会比小模型更好,但我不认为它们在任何特定功能集上的表现会显著优于灵活的、针对性的、基于检索的模型。

与巨型模型相比,灵活模型有许多优点,尤其是当模型是针对性的和基于检索的时,这些优点会得到进一步增强。这些好处包括:

  • 可持续且成本较低的模型: 模型在训练和推理计算上具有显著较低的成本。推理运行时计算成本可能是 24x7 使用的商业导向模型可行性的决定因素,并且在广泛部署中整体环境影响的大幅减少也很显著。最后,凭借其可持续、特定和功能导向的系统,灵活模型并不试图解决人工通用智能(AGI)的雄心勃勃的目标,因此在与后者相关的公共和监管辩论中参与较少。

  • 更快的微调迭代: 较小的模型可以在几小时(或更短时间)内完成微调,通过类似 LoRA 的适应方法向模型添加新信息或功能,这在灵活模型中非常有效。这使得改进周期更频繁,使模型始终与其使用需求保持同步。

  • 基于检索的模型优点: 检索系统重新组织知识,从直接来源引用大部分信息,而不是模型的参数记忆。这改善了以下方面:

    可解释性: 检索模型使用源属性,提供来源或能够追溯到信息来源的能力,以提供可信度。

    时效性: 一旦索引了最新的来源,模型可以立即使用,无需任何训练或微调。这允许在接近实时的情况下不断添加或更新相关信息。

    数据范围: 为按需检索编制的信息可以非常广泛和详细。当集中在目标领域时,模型可以覆盖大量的私有和公共数据的范围和深度。它可能在其目标空间中包含比巨型基础模型训练数据集更多的量和细节。

    准确性: 直接访问数据的原始形式、细节和上下文可以减少幻觉和数据近似。只要在检索范围内,就可以提供可靠和完整的答案。使用较小的模型时,按需检索的可追溯策划信息和(如巨型模型中)可能过时、部分且未标注来源的记忆信息之间的冲突也更少。

  • 硬件选择: 灵活模型的推理可以在任何硬件上实际完成,包括可能已经是计算设置一部分的普遍解决方案。例如,Meta 的 Llama 2 灵活模型(7B 和 13B 参数)在英特尔的数据中心产品上运行良好,包括 Xeon、Gaudi2 和 Intel 数据中心 GPU Max 系列。

  • 集成、安全和隐私: 今天的 ChatGPT 和其他巨型 GenAI 模型是独立模型,通常在第三方平台上的大型加速器设施上运行,并通过接口访问。灵活的 AI 模型可以作为嵌入到更大业务应用程序中的引擎运行,并且可以完全集成到本地计算环境中。这对于安全和隐私有重大影响,因为不需要与第三方模型和计算环境交换/暴露信息,而且更广泛应用的所有安全机制都可以应用于 GenAI 引擎。

  • 优化和模型缩减: 优化和模型缩减技术,如量化,通过将输入值转换为较小的输出值来减少计算需求,在增加功率效率的灵活模型上已经显示出了强大的初步结果。

检索模型需要对所有源数据进行索引: 模型在推断期间通过索引映射获取所需信息,但存在错过信息源的风险,使其对模型不可用。为了确保来源可追溯性、可解释性和其他属性,针对检索型模型不应依赖于存储在参数记忆中的详细信息,而应主要依赖于在需要时可用于提取的索引信息。

  • 任务范围减少: 通用巨型模型具有出色的多功能性,特别擅长于未曾考虑的零-shot 新用途。灵活系统能够实现的广度和范围目前仍在评估中,但似乎随着最近的模型而有所改善。目标模型假定任务范围在预训练和/或微调期间已知和定义,因此范围的缩减不应影响任何相关能力。目标模型不是单一任务,而是一组相关能力。这可能会导致由于任务或业务特定的灵活模型而产生的碎片化。

  • 可能通过少量样本的精细调整来改进: 为了有效地解决目标空间的模型,不总是需要进行精细调整,但可以通过调整模型以适应应用程序所需的任务和信息来提高 AI 的效果。现代技术使得这一过程可以用少量示例完成,而无需深入的数据科学专业知识。

  • 在 Intel CPU 上的生成 AI 模型已经显示了强大的初步结果

摘要

生成 AI 的重大飞跃使得新的能力成为可能,例如 AI 代理以自然语言交谈、引人入胜的文本总结和生成、图像创作、利用先前迭代的上下文等。本文介绍了“灵活 AI”这一术语,并阐述了为什么它将成为大规模部署生成 AI 的主要方法。简单来说,灵活 AI 模型运行更快,通过持续微调更新更迅速,并且通过开源社区的集体创新,更容易进行快速技术改进。

通过多个示例展示,随着最大模型的进化,表现出的卓越性能表明,灵活模型不需要像巨型模型那样的庞大体积。一旦掌握了基本认知能力,调整了所需功能,并根据需要提供数据,灵活模型为商业世界提供了最高的价值。

尽管如此,灵活模型不会使巨型模型灭绝。巨型模型在零-shot、开箱即用的设置中仍然有更好的表现。这些大型模型也可能被用作蒸馏成较小灵活模型的来源(教师模型)。虽然巨型模型拥有大量额外的记忆信息来处理任何潜在的用途,并且配备了多种技能,但这种通用性不被期望在大多数生成 AI 应用中需要。相反,将模型微调到与领域相关的信息和技能,并能够从策划的本地和全球来源中检索最新信息,将为许多应用提供更好的价值主张。

将灵活、针对性的 AI 模型视为可以集成到任何现有应用中的模块,提供了非常有吸引力的价值主张,包括:

  • 部署和操作成本仅为其一小部分。

  • 适应任务和私人/企业数据。

  • 每晚更新,并且可以在从 CPU 到 GPU 或加速器的任何硬件上运行。

  • 集成到当前计算环境和应用中。

  • 运行在本地或私有云中。

  • 受益于所有的安全和隐私设置。

  • 更高的准确性和可解释性。

  • 在提供类似生成 AI 能力的同时,更具环保责任感。

在少量巨型模型上取得的令人印象深刻的进展将继续。然而,行业最可能需要的只是几十个通用的灵活基础模型,这些模型可以用来构建无数的目标版本。我预见到不久的将来,广泛扩展的高级生成 AI 将渗透到所有行业,主要通过将灵活、针对性的安全智能模块作为增长引擎。

参考资料

  1. Tseng, P. K. (2023 年 3 月 1 日). TrendForce 表示,由于云公司发起 AI 军备竞赛,ChatGPT 对 GPU 的需求可能达到 30,000 芯片,为商业化做好准备。TrendForcewww.trendforce.com/presscenter/news/20230301-11584.html

  2. 介绍 MPT-7B:开源、商业可用 LLM 的新标准。 (2023 年 5 月 5 日)。 www.mosaicml.com/blog/mpt-7b

  3. Mukherjee, S., Mitra, A., Jawahar, G., Agarwal, S., Palangi, H., & Awadallah, A. (2023). Orca:从 GPT-4 的复杂解释轨迹中逐步学习。arXiv (康奈尔大学)doi.org/10.48550/arxiv.2306.02707

  4. Wolfram, S. (2023 年 3 月 23 日). ChatGPT 获得了“Wolfram 超能力”!Stephen Wolfram Writingswritings.stephenwolfram.com/2023/03/chatgpt-gets-its-wolfram-superpowers/

  5. Schreiner, M. (2023 年 7 月 11 日). GPT-4 架构、数据集、成本等泄露。THE DECODERthe-decoder.com/gpt-4-architecture-datasets-costs-and-more-leaked/

  6. ChatGPT 插件。 (无日期)。 openai.com/blog/chatgpt-plugins

  7. Izacard, G., Caron, M., Hosseini, L., Riedel, S., Bojanowski, P., Joulin, A., & Grave, E. (2021). 使用对比学习进行无监督密集信息检索。arXiv (康奈尔大学)doi.org/10.48550/arxiv.2112.09118

  8. Mallen, A., Asai, A., Zhong, V., Das, R., Hajishirzi, H., 和 Khashabi, D. (2022). 何时不信任语言模型:调查参数化和非参数化记忆的有效性。arXiv (康奈尔大学)doi.org/10.48550/arxiv.2212.10511

  9. Papers with Code — PopQA 数据集。 (无日期)。 paperswithcode.com/dataset/popqa

  10. 介绍 LLaMA:一个基础的 65 亿参数的大型语言模型。 (2023 年 2 月 24 日)。 ai.facebook.com/blog/large-language-model-llama-meta-ai/

  11. 介绍 Falcon LLM。 (无日期)。 falconllm.tii.ae/

  12. Nijkamp, E., Hayashi, H., Xie, T., Xia, C., Pang, B., Meng, R., Kryscinski, W., Tu, L., Bhat, M., Yavuz, S., Xing, C., Vig, J., Murakhovs’ka, L., Wu, C. S., Zhou, Y., Joty, S. R., Xiong, C., 和 Savarese, S. (2023). 使用 XGen 进行长序列建模:一个在 8K 输入序列长度上训练的 7B LLM。Salesforce AI Researchblog.salesforceairesearch.com/xgen/

  13. Hu, E. J., Shen, Y., Wallis, P., Allen-Zhu, Z., Li, Y., Wang, S., Wang, L., 和 Chen, W. (2021 年 6 月 17 日). LoRA:大型语言模型的低秩适应。arXiv (康奈尔大学). doi.org/10.48550/arXiv.2106.09685

  14. Lewis, P., Perez, E., Piktus, A., Petroni, F., Karpukhin, V., Goyal, N., Küttler, H., Lewis, M., Yih, W., Rocktäschel, T., Riedel, S., 和 Kiela, D. (2020). 针对知识密集型 NLP 任务的检索增强生成。NeurIPS 2020. proceedings.neurips.cc/paper/2020/hash/6b493230205f780e1bc26945df7481e5-Abstract.html

  15. Introduction LangChain. (无日期). python.langchain.com/docs/get_started/introduction.html

  16. Haystack. (无日期). www.haystackteam.com/core/knowledge

  17. Mantium. (2023). Haystack 和 LangChain 如何赋能大型语言模型。Mantium. mantiumai.com/blog/how-haystack-and-langchain-are-empowering-large-language-models/

  18. Taori, R., Gulrajani, I., Zhang, T., Dubois, Y., Li, X., Guestrin, C., Liang, P., 和 Hashimoto, T. B. (2023 年 3 月 13 日). Alpaca:一个强大且可复制的指令跟随模型。斯坦福大学 CRFM. crfm.stanford.edu/2023/03/13/alpaca.html

  19. Geng, X., Gudibande, A., Liu, H., Wallace, E., Abbeel, P., Levine, S. 和 Song, D. (2023 年 4 月 3 日). Koala:一个用于学术研究的对话模型。伯克利人工智能研究博客. bair.berkeley.edu/blog/2023/04/03/koala/

  20. Chiang, W. L., Li, Z., Lin, Z., Sheng, Y., Wu, Z., Zhang, H., Zheng, L., Zhuang, S., Zhuang, Y., Gonzalez, J. E., Stoica, I., 和 Xing, E. P. (2023 年 3 月 30 日). Vicuna:一个令人印象深刻的开源聊天机器人,媲美 GPT-4,*质量达到 90%*的 ChatGPT。LMSYS Org. lmsys.org/blog/2023-03-30-vicuna/

  21. Rodriguez, J. (2023 年 4 月 5 日). 认识 Vicuna:最新的 Meta 的 Llama 模型,与 ChatGPT 性能相当。Medium. pub.towardsai.net/meet-vicuna-the-latest-metas-llama-model-that-matches-chatgpt-performance-e23b2fc67e6b

  22. Papers with Code — BIG-bench 数据集. (无日期). paperswithcode.com/dataset/big-bench

  23. Meta. (2023 年 7 月 18 日). Meta 和微软推出下一代 Llama。Meta. about.fb.com/news/2023/07/llama-2/

  24. Meta AI. (无日期). 介绍 Llama 2。 ai.meta.com/llama/

  25. Gunasekar, S., Zhang, Y., Aneja, J., Mendes, C. C. T., Allie, D. G., Gopi, S., Javaheripi, M., Kauffmann, P., Gustavo, D. R., Saarikivi, O., Salim, A., Shah, S., Behl, H. S., Wang, X., Bubeck, S., Eldan, R., Kalai, A. T., Lee, Y. T., 和 Li, Y. (2023). 教科书就是你所需的一切。arXiv (康奈尔大学)doi.org/10.48550/arxiv.2306.11644

  26. Toma, A., Lawler, P. R., Ba, J., Krishnan, R. G., Rubin, B. B., 和 Wang, B. (2023). Clinical Camel: 一个开源的专家级医疗语言模型,具有基于对话的知识编码。arXiv (康奈尔大学)doi.org/10.48550/arxiv.2305.12031

  27. Patel, D., 和 Ahmad, A. (2023 年 5 月 4 日). Google “我们没有护城河,OpenAI 也没有。” SemiAnalysis。 www.semianalysis.com/p/google-we-have-no-moat-and-neither

  28. 加速 Llama 2 通过英特尔 AI 硬件和软件优化。(无日期)。英特尔。 www.intel.com/content/www/us/en/developer/articles/news/llama2.html

  29. 更小更好:Q8-Chat,在 Xeon 上的高效生成 AI 体验。(无日期)。Hugging Face。 huggingface.co/blog/generative-ai-models-on-intel-cpu

分析车辆尺寸与行人安全

原文:towardsdatascience.com/suvs-are-killing-people-de6ce08bac3d

公开的交通事故数据表明,SUV 导致行人死亡和受伤的比例高于小型汽车

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Danny Cunningham

·发布于Towards Data Science ·8 分钟阅读·2023 年 1 月 10 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由Alexandru Acea提供,来源于Unsplash

《纽约时报》最近强调了“极具美国特色”的道路死亡上升问题。除了美国之外,几乎所有发达国家的道路变得越来越安全。即使在 COVID-19 疫情高峰期,当时道路上的汽车大幅减少,交通死亡人数仍在增加

美国的道路对行人特别危险。保险公路安全研究所(IIHS)2022 年 3 月的一项研究发现,自 2009 年以来,行人死亡人数增加了 59%,而 2020 年所有机动车死亡中有 20%是行人。导致这些严峻统计数据的因素有很多,但一个主要因素(言外之意)是道路上车辆的尺寸。

大型 SUV 和皮卡车由于其较大的重量和更高的前端,明显比小型汽车更容易伤害或杀死行人。而且,如果你生活在美国,你肯定会注意到,美国人喜欢大型车辆。一些报告显示,现在超过 80%的新车销售在美国是 SUV 或皮卡。这对行人来说是个坏消息。并且我们还将面临荒谬沉重的电动汽车

但我们真的可以将这些行人安全统计数据视为绝对真实吗?我决定自己分析数据,以查看大型车辆是否确实导致了行人伤害和死亡的显著增加(剧透:确实如此)。

以下分析的所有代码可以在 GitHub 上的 Jupyter 笔记本中找到。该笔记本包含了本文中未包含的额外细节。

数据

我分析了我所在城市芝加哥的数据。芝加哥发布了交通碰撞数据(以及大量其他数据集),并通过 Socrata API 公开提供。开始使用 Socrata 数据集很简单:只需按照文档获取应用程序令牌,找到你感兴趣的 API 端点,然后开始查询。我使用了sodapy Python 包来与 API 交互。

具体来说,我使用了与芝加哥交通碰撞相关的三个数据集:

  • 碰撞记录:有关碰撞的基本细节,例如发生的时间和地点。每次碰撞一个记录。

  • 人员记录:有关涉及碰撞的人员的详细信息。识别一个人是否受伤,以及他们是司机还是行人。每次碰撞至少一个记录。

  • 车辆:涉及碰撞的车辆的详细信息。包括品牌、型号和车辆类型。每次碰撞至少包含一条记录。

这些数据集中的数据是由每次碰撞事件中的报告警官收集的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Sawyer Bengtson 提供,来源于 Unsplash

方法论

分析的目标是确定大型车辆(SUV 和皮卡)是否比小型汽车更可能致使行人遇难或严重受伤。我们将通过拟合逻辑回归模型来实现这一点,该模型将显示哪些因素在决定伤害是否发生中是相关的。

定义目标变量和特征

在拟合模型之前,我们需要将原始数据转换为模型可以使用的格式。这意味着我们需要定义我们的目标变量(我们试图预测的内容)和一些特征(我们将用来进行预测的内容)。

在我们的案例中,目标变量是一个二进制值,指示在碰撞中是否有行人遇难或严重受伤(1 = 受伤,0 = 无受伤)。这可以从 People 数据集中轻松计算得出。首先,我们通过“person_type”字段确定碰撞中的人员是否为行人。然后,我们使用“injury_classification”字段确定是否有任何行人受到了致残性或致命伤害。我们实际上会在这里创建两个目标变量——一个用于致残伤害,一个用于致命伤害——并在后续单独建模。(注:数据集将致残性伤害定义为“阻止受伤者行走、驾驶或正常继续其能够进行的活动”的任何伤害。)

我们需要包括的主要特征是车辆类型。这通常比较简单,因为车辆数据集中包含了区分汽车、SUV、皮卡等的分类。然而,数据集中对车辆的标注并不一致。例如,一位警官可能将一辆丰田 RAV4 标记为 SUV,而另一位警官可能将其标记为汽车。为了考虑这些差异,我们将检查每个品牌/型号最常被标记的类别,并将其用于该品牌/型号的所有实例。在完成这小部分特征工程后,我们可以很容易地为每次碰撞计算两个二进制特征:一个表示是否涉及 SUV,另一个表示是否涉及皮卡。

我们还应该控制其他可能影响碰撞结果的因素,如天气条件和限速。我们将通过在回归模型中包括额外的特征来做到这一点,这将使我们能够估计每个单独特征的独立效应。

最后,我们将从数据集中移除所有不涉及行人的事故,因为这些事故与当前的问题无关。

逻辑回归模型

我们试图回答的问题可以很容易地框定为一个二元分类问题。根据关于事故的信息,预测行人是否会被杀害(或受伤)。在我们的用例中,理解为什么做出这种预测也是至关重要的。

逻辑回归是一个不错的选择,因为它产生了一个简单且易于解释的模型。我们将能够分析模型以了解哪些特征对目标变量的概率有正面或负面影响。具体来说,我们将能够看到车辆类型是否对行人死亡和受伤有显著影响。

逻辑回归的完整数学推导超出了本文的范围,但本质上模型会产生一个线性预测器:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中β系数表示每个特征X对目标变量的影响。我们可以将系数转换为易于解释的赔率比(例如,当车辆是 SUV 时,行人受伤的可能性增加Z%)。

我们将拟合两个独立的逻辑回归模型:一个用于预测行人死亡,另一个用于预测行人致残伤害(包括死亡)。除了目标变量外,模型结构是相同的。

假设

我们在模型中做了几个假设,无论是明确还是隐含的:

  1. SUV 和较小的汽车在涉及行人的事故中发生率相同。我们只是在预测事故的结果,而不是预测事故是否会因不同的汽车而发生。(注意: 有一些证据 表明 SUV 撞击行人的频率高于小型汽车,这可能会质疑这一假设。如果这确实是事实,那么 SUV 对行人死亡的影响可能比下面的结果所显示的更糟。)

  2. 所有 SUV 都是相同的(所有皮卡车也是如此)。显然,在现实世界中情况并非如此,因为 SUV 的形状和尺寸差异很大。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

显然,这两辆 SUV 并不相同,但在模型中被视为相同。图像已获得求助于 carsized.com的许可。

结果

那么 SUV 和皮卡车对行人更危险吗?是的。

逻辑回归模型显示,与较小的汽车相比,SUV 更可能导致 16%的致残伤害和 36%的行人死亡。皮卡车导致致残伤害的可能性增加 33%,导致行人死亡的可能性增加 108%(是两倍多!)。

模型预测,在过去五年中,由于 SUV 和皮卡车,芝加哥大约发生了 20 起额外死亡(即,如果这些车辆被更小的汽车替代,这些死亡将不会发生)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2017 到 2022 年间,205 名行人被个人车辆撞击致死。如果 SUV 和皮卡车被更小的汽车替代,大约可以拯救 20 条生命。(图像由作者提供)

模型还识别了一些其他有趣(但可能并不完全令人惊讶)的因素,这些因素导致了行人死亡。下表显示了模型发现的所有统计显著特征的影响。以下是关键发现的总结:

  • 大型车辆对行人更危险。 SUV 和皮卡车在统计上更可能造成致残伤害。这是一个相当明显的结果,也是本文的主要话题。

  • 高速行驶对行人危险。 更重要的是,允许高速的条件对行人危险。这最明显地表现为与限速的正相关关系,但也通过其他特征显示出来(有更多车道或由中央隔离带分隔的道路通常允许更高速度;停车场则不允许)。令人惊讶的是,雪天条件降低了行人受伤的可能性。这可能是因为雪天道路迫使汽车减速行驶。

  • 低能见度条件对行人危险。 晚上的伤害概率增加。巷道中的碰撞也可能导致伤害,这可能是因为司机在狭窄的巷道中能见度降低(且巷道中可能有行人与车辆共同通过)。

  • 在 COVID 期间,严重的行人伤害变得更加常见。 即使在控制了数据集中的其他特征时,COVID-19 大流行期间行为也发生了统计学上显著的变化。模型中添加了两个二元日期特征(“高峰 COVID”和“高峰后 COVID”)以解释这种差异。这可能归因于疫情高峰期街道更空旷导致速度更快。 (注:致残伤害的总数不一定增加;模型检测到的是 COVID 期间致残伤害的发生率增加。)

下表显示了支持上述总结信息的数据点,更多细节(如置信区间)可以在GitHub上找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一张表格总结了各种碰撞特征对行人致残伤害可能性的影响。特征只有在模型识别为统计显著(p < 0.05)时才被包含。“相对几率”+X% 表示如果该特征为真(或对于数值特征增加一个单位),而其他碰撞特征保持不变,那么致残伤害的可能性提高了 X%

结论…我们可以对此做些什么?

我们得出的结论是——请鼓掌!——比起小型、轻型汽车,大型、重型汽车更容易致使行人死亡。好吧…这并不算突破性发现。然而,许多人没有意识到这是我们城市中的一个问题——直到被指出来我才想到这个问题。我希望一些有力的证据能提高人们的意识。

那我们能做些什么呢?

首先,如果你开的是 SUV 或皮卡车,这并不意味着你是一个坏人。我甚至不会试图劝你不要买这种车。人们购买这些车辆有很多原因(其中一些理由可能还是真正有效的)。

值得注意的是,SUV 确实在碰撞中能使驾驶员更安全。这就形成了一个每个驾驶员都被激励购买大型车辆的情况,但如果每个人都做出这个决定,整个系统对所有人(特别是车外的人)来说会变得更危险。在这种“安全军备竞赛”场景中,唯一无可争议受益的群体是那些宁愿向你出售昂贵 SUV 而不是便宜轿车的汽车公司。

冒着有点政治风险的说,解决这个问题的一种方法是通过法规。例如,欧洲车辆安全法规包括了行人安全的条款;而美国的安全法规则没有。下次去投票的时候,尤其是在地方选举中,值得记住这一点,因为当选官员实际上能影响你所在城市的街道。

成为 Medium 会员以获取成千上万作家的故事!

Svelte & 数据可视化

原文:towardsdatascience.com/svelte-data-visualisation-6210e8164e74

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Svelte 条形图(来源:作者,2023 年)

使用 Svelte 创建交互式条形图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Sutan Mufti

·发表于 Towards Data Science ·阅读时间 6 分钟·2023 年 3 月 20 日

介绍

数据可视化揭示了我们数据中的信息。通常的方法是制作图表或地图。我们可以在诸如 Microsoft Excel 或 Google Sheets 的电子表格软件中完成这项工作。通常这已经足够了,但我们可以通过添加交互性来使其更具吸引力。一个简单的交互性添加例子是通过添加切片器来根据类别筛选数据。在 Microsoft Excel 中,我们可以启用“开发者”选项卡并添加表单元素,如按钮、复选框等。

使用现代软件技术,创建这种交互式数据体验的经典工具是使用 d3.js 以及原生 JavaScript。它的工作原理如此简单,却能产生美丽的结果,真是令人惊叹。然而,与 React、Angular、Vue 等现代框架相比,原生 JavaScript 感觉有些过时。虽然大家都知道这些框架,但我觉得有一个用于数据可视化的 UI 框架被低估了;你从标题中猜到它就是 Svelte。考虑到它的年轻生态系统,我认为这个出色的框架需要被推广,以便让更多人使用或开发它;尤其是在数据科学领域。

本文展示了 Svelte 在交互式数据可视化中的应用(代码链接见下文的 GitHub 链接)。首先,我将简要说明其区别于其他框架的特性。其次,我将概述我们将要可视化的数据和我们的特性。最后,我将解释一些代码片段的工作原理;我更侧重于理念而不是语法。最后,我们将制作一个如文章主要 gif 图片所示的交互式数据 UI。

代码

代码可在以下链接获取。

[## GitHub - sutanmufti/svelte-data-visualisation: 使用 svelte 可视化数据

由 Sutan Mufti(2023)创建的这段代码是 RekayasaData.co.uk 项目的一部分。这个代码库托管了代码……

github.com

演示

你可以在这里找到演示:

[## 伦敦人口数据 2023

演示

ceritapeta.co.uk

什么是 Svelte?

Svelte 是一个通过将其文件编译成纯 HTML + JavaScript 和 CSS 来创建用户界面的框架。Svelte-kit 是开发 svelte 应用程序的新元框架。它刚刚在去年 12 月(2022)达到 v1.0。这是一个很好的工具来开始和管理 svelte 应用程序。

在使用 Svelte 几个月后,我爱上了这个框架,因为它的惊人功能。个人认为,这些功能让它脱颖而出,并提供了出色的开发体验。对于数据科学和可视化,我认为这些功能最为有用:

  • HMR(热模块替换):在开发过程中,应用程序在我们更改代码时保持其状态。这意味着实时更改会直接反映在浏览器中,同时保持变量。

  • 原生响应性:这将作为本文中我们应用的主要功能进行演示!我们不需要在 svelte 中管理状态。如果你熟悉 React,这相当于useState钩子。虽然,我们仍然需要管理多个组件之间的状态连接。一个非常简短的代码来演示这个功能;点击一个按钮,生成一个随机数,并在 HTML 元素中显示它

<!-- ./randomiser.svelte -->
<script lang='ts'>
    let theValue: number = 40;
    function randomiser(){theValue = Math.floor(Math.random() * 100);}
</script>
<button on:click={randomiser}>random!</button><br>
<p>the value: {theValue}</p>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随机器应用(来源:作者,2023)

你可以按原样将上述代码粘贴到 svelte 文件中!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随机器应用代码(来源:作者,2023)

  • 数据绑定:类似于Document.querySelectorbind语法将一个元素绑定到脚本的变量上。我认为这种方式管理 HTML 元素更简单。我在 github 代码库中提供了一个循环和绑定的示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

绑定(来源:作者,2023)

构建界面

构建界面需要 HTML、JavaScript 和 CSS 的知识。我更喜欢 typescript 来减少 bug 开发,因为它使我们编写的代码比纯 JavaScript 更严格。现在,让我们使用这些功能(绑定、响应性和 HMR)。我将讨论的步骤是:

  • 使用+layout.svelte设置主题

  • 使用 ES6 语法设置要导入的数据

  • 整合各个部分

设置主题

首先,我喜欢从根布局的样式开始。+layout.svelte文件定义了所有 Svelte 文件的行为。在这个文件中,我只设置了字体、颜色、边距和背景颜色。这基本上是应用的“主题”。为了这个演示,我们保持简单,至少它不是默认的。

<!-- +layout.svelte -->
<svelte:head>

    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            color: #303030;
            margin: 0;
            background-color: #ebebeb;

        }

    </style>
</svelte:head>

<slot></slot>

设置数据

在这个演示中,我们将使用来自英国大伦敦地区的人口数据。你可以在这里找到这些数据。数据格式为 csv,建议将其转换为 JSON 格式。使用pandas非常简单,因为有to_json("data.json", orient="record")。请注意orient参数,它表示一种无模式的风格数据,类似于 MongoDB。这样,我们可以在 Javascript 中使用forEachmap方法来处理一个数组。

在 ES6 语法中,我们可以使用import从其他脚本文件中导入变量或对象。由于我们的数据基本上是 JSON,我们可以像这样将其定义为一个变量:

// data.ts
export const data = [
  {name: "sutan", article: "Visualising Data with Svelte"},
  {name: "sutan", article: "Spatial Data Science"},
  {name: "someone", article: "somedata"}
  //... and many more rows
]

然后我们可以将数据导入并解构到主脚本文件中。

// main.ts

import {data} from './data.ts'

interface Record {
  name: string;
  article: string;
}

function main(data: Record[]){
  data.forEach(record=>console.log(`${record.name} wrote ${record.article}`))
}
main(data)

在我的示例中,我们将伦敦人口数据存储在./src/routes/population_london.ts文件中,变量名为LondonData

构建应用

让我们将这一部分分成两个小节:处理用户事件和实际可视化数据。

绑定与用户事件

首先,我们创建一个选项表单字段,用户可以用来选择一个区。请查看以下代码,我们使用bind将表单值绑定到selectionIndex。在未来的组件中,我们可以使用selectionIndex,它会根据用户的事件动态变化。

<div>
    density of
    <select bind:value={selectionIndex}>
        {#each data as d,i}
            <option value={i}>{d.Name}</option>
        {/each}
    </select>
    is {selectedDensity} per square km
</div>

数据可视化

借用 d3.js 开发范式的理念,我使用 SVG 来可视化图形。Svelte 提供了原生的each语法来循环变量。对于我们的人口数据中的每条记录,我们想要创建一个矩形,并将高度设置为密度数据。查看rectheight属性。

然后,on:click属性处理用户点击条形图时的点击事件。它的回调执行一个函数,该函数接受矩形索引作为参数。activateSelection(index: number)基本上设置了前一节中绑定的selectionIndex。当selectionIndex改变时,选择选项表单的值也会改变。

<svg width={data.length * barwidth / 100} height={maxHeight} >
    <g >
        {#each data as d,i}
        <rect  height={d.Population_per_square_kilometre / scaling} y={maxHeight - d.Population_per_square_kilometre / scaling} width={barwidth/100*0.8}  x={(i * barwidth / 100 * 1)} fill={(i == selectionIndex)? "black": "grey"} on:click={()=>{return activateSelection(i)}} on:keydown={()=>{}}></rect>
        {/each}
    </g>
</svg>

d3.js 中的等效代码如下:

// usingD3.js
const graph = d3
.select("svg")
.selectAll("rect")
.data(LondonData)
.enter()
.append("rect")
.attr("width", (d)=>d.Population_per_square_kilometre)
.on("click",handleClick)

演示

使用静态适配器,我们可以将其构建为普通的index.html文件,以便在如 apache httpd 这样的 Web 服务器中静态服务。以下链接是已发布的演示,也是在文章顶部的主要图片。

[## 伦敦人口数据 2023

演示使用 Svelte! ceritapeta.co.uk

结论

我认为 Svelte 是一个被低估的工具,特别是在交互式数据可视化方面。在这个演示中,我们甚至不需要额外的库来进行数据可视化,只需导入数据并使用 Svelte 进行显示。目前一切都是静态的,因为我认为这样足以展示可视化部分。更有趣的是,我们在这篇文章中还没有探讨 Svelte 的全部潜力。例如,可以利用 +server.js 构建 API 并将其集成到我们的应用中;或者使用过渡效果;或者构建组件以增强图表的外观。可以确定的是:

Svelte 在数据可视化方面的未来令人兴奋。

我希望你觉得这篇文章有用。谢谢阅读。

大型语言模型(LLMs)的软件/硬件协同优化策略

原文:towardsdatascience.com/sw-hw-co-optimization-strategy-for-large-language-models-llms-855f20a14629

如何最大限度地发挥系统性能以加速运行 LLMs?— 最佳实践

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Liz Li

·发表在Towards Data Science ·5 分钟阅读·2023 年 12 月 16 日

领先的大型语言模型(LLMs)如 ChatGPT、Llama 等正在革新科技行业并影响每个人的生活。然而,它们的成本构成了一个重大障碍。使用 OpenAI API 的应用会产生持续的高费用(每 1,000 个提示令牌$0.03,每 1,000 个采样令牌$0.06)。

为了降低成本,公司倾向于托管自己的 LLMs,费用因模型大小而异(100–200B 参数的大型 LLMs 成本约为 7–15B 参数的小型模型的 10 倍)。这一趋势催生了 AI 芯片竞赛,各大科技公司旨在开发自己的 AI 芯片,减少对昂贵硬件的依赖。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型大小的趋势。来源:AWS reInvent

如何挤压每一丝计算能力以运行 LLMs?在这篇文章中,我将对 LLM 的优化策略进行深入分析,涵盖模型、软件和硬件。这将遵循我在之前文章中编写的 AI SW/HW 协同设计方法论,并对 LLM 特有的成本和性能优化进行更深入的探讨。

## 如何在新时代共同设计 AI/ML 的软件/硬件架构?

对 AI/ML 高效架构设计的全面视角

towardsdatascience.com 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:作者及其他同事制作

运行 LLM 模型的计算和内存需求正在呈指数级增长,而计算/内存能力却在较慢的轨迹上滞后,如上图所示。为了弥补这种性能差距,探索三个关键领域的改进是至关重要的:

  1. 算法改进与模型压缩: 我们如何通过增强模型特性来减少计算和内存需求而不影响质量?最新的 LLM 量化技术有哪些进展,能在保持质量的同时减少模型大小?

  2. 高效的软件栈与加速库: 在构建能够无缝连接 AI 模型和硬件的软件栈时,哪些考虑因素至关重要?我们如何利用硬件特性来优化 LLM 加速?现有的软件挑战和潜在的改进有哪些?

  3. 强大的 AI 硬件加速与先进的内存层次结构: 当前有哪些针对 LLM 的硬件加速器?我们如何通过内存层次结构的潜在改进来缓解高内存需求?

我将为上述每个主题撰写一篇文章。在这篇文章中,我们将深入探讨第一个主题(算法改进与模型压缩)!

LLM 基于变换器架构(编码器-解码器),其中包括仅解码器模型架构如 Llama、ChatGPT 等,以及编码器-解码器模型架构如 Whisper、T5 等。新兴模型每天都在出现。在这篇文章中,我们将重点关注以下四个新特性来加速变换器的性能。

1. 量化

将 FP32 模型转换为 INT8 模型可以将内存大小缩小约 4 倍,而 INT4 量化则能实现大约 8 倍的模型大小减少。此外,整数矩阵乘法的计算成本显著降低,因为其速度超过了浮点计算。量化分为两类——后训练量化(PTQ)和量化感知训练(QAT)。对于推理,推荐使用 PTQ。Hugging Face 托管了大量利用各种量化方法如 GPTQ、GGUF、AWQ 等的量化 LLM 模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过量化实现模型大小的减少。来源:huggingface.co/TheBloke

2. 注意力机制

缩放点积注意力计算密集,涉及多次矩阵乘法键、查询和数值。在多头注意力中,存在多个注意力层(称为头),每个头生成的输出都会被拼接在一起。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个缩放点积注意力(左)和多头注意力(右)的示意图,多头注意力实际上是多个 SDPA 头并行。来源:注意力机制就是一切 [参考 1]

为了优化注意力推理,引入了多查询注意力的概念(参考 [2] 快速变换器解码)。在这种方法中,键和值在不同的注意力头之间共享,减少了为每个注意力头获取新键值对的需求,最小化了数据传输。

此外,在多头注意力和多查询注意力之间存在一种中间机制,称为分组查询注意力。它涉及将键和值投影到不同的组中,这与多查询注意力中的单一投影不同。这种方法在保持模型质量的同时有效减少了内存需求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不同注意力机制的比较。来源: GQA: 从多头检查点训练通用多查询变换器模型 [Ref 3]

Flash Attention(参考 [4])。与传统的逐层计算方法不同,Flash Attention 使用平铺技术将多个层融合在一起,并在单次操作中计算出最终结果。平铺大小考虑了系统内存层次结构,优化了 IO 操作。下图演示了 Flash Attention 与 PyTorch 原生实现相比的概念和延迟改进。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 40 GB GPU 上使用的平铺 Flash 注意力计算模式和内存层次结构。来源:Flash Attention: 快速且内存高效的精确注意力与 IO 感知

3. 分页 KV 缓存

随着输入和输出标记数量的增加,键值缓存可能变得非常庞大,具有动态长度,这导致由于碎片化和冗余复制而造成的内存访问效率低下。受到操作系统中虚拟内存机制的启发,Paged Attention 旨在最小化 KV 缓存内存中的冗余,并促进 KV 缓存在请求内和跨请求的灵活共享。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

左侧:参数(灰色)在每次服务请求中保持在内存和 KV 缓存(红色)中。右侧:vLLM 有助于减缓内存需求以提升系统吞吐量。来源:大语言模型服务的高效内存管理与 PagedAttention [Ref 5]

4. 推测采样 [参考 6]

在自回归生成模型中,生成单个标记需要完整的模型推理,这会导致重复的权重加载,耗时较长。推测采样旨在缩小小型模型和大型模型之间的差距,通过提供类似于大型模型的高质量结果,同时具有类似于小型模型的更快速度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWQ 引擎显著加快了猜测性解码的速度。来源:在快速车道上!猜测性解码 — 10 倍更大的模型,无额外成本

除了从算法和模型的角度提到的四大推理加速技术,还有许多其他特性可以加速 LLM 模型的推理。这些包括模型/张量并行、模型稀疏性、知识蒸馏等,新的研究也在不断涌现。利用这些技术对加速 LLM 解决方案至关重要。

需要注意的是,优化 AI 工作负载总是涉及模型、软件和硬件方面的协同。在即将发布的文章中,我们将深入探讨 LLM 加速的软件栈/库和硬件架构方面,敬请关注!

参考文献

[1] Ashish Vaswani 等人,注意力即你所需,NIPS 2017,加州长滩

[2] Noam Shazeer,快速 Transformer 解码:一个写头就足够,2019,arxiv

[3] Joshua Ainslie 等人,GQA:从多头检查点训练通用多查询 Transformer 模型,2023

[4] Tri Dao 等人,Flash Attention:具有 IO 感知的快速且内存高效的精确注意力,2022,arxiv

[5] Woosuk Kwon 等人,大语言模型服务的高效内存管理与 PagedAttention,2023,arxiv

[6] Charlie Chen 等人,使用猜测性采样加速大语言模型解码,2023,arxiv

LLM 和 GUI 的协同作用,超越聊天机器人

原文:towardsdatascience.com/synergy-of-llm-and-gui-beyond-the-chatbot-c8b0e08c6801?source=collection_archive---------3-----------------------#2023-10-20

使用 OpenAI GPT 功能调用来驱动你的移动应用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 汉斯·范·达姆

·

关注 发布于 Towards Data Science ·10 分钟阅读·2023 年 10 月 20 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Midjourney 创建

介绍

我们引入了一种激进的用户体验(UX)方法,以最佳方式将对话式人工智能(Conversational AI)与图形用户界面(GUI)交互融合,形式为自然语言条。它位于每个屏幕的底部,允许用户通过一个入口点与整个应用程序进行交互。用户始终可以选择语言或直接操作。他们无需搜索如何完成任务,可以用自己的语言表达意图,同时保持 GUI 的速度、紧凑性和可操作性。GUI 的屏幕定义与用户的请求一起发送到大型语言模型(LLM),让 LLM 引导 GUI 朝向用户的意图。我们在上一篇文章中介绍了这一概念,并在此基础上进行了优化,实施了一个 Flutter 示例应用程序,点击这里试用。完整的 Flutter 代码可以在 GitHub 上找到,因此你可以在自己的上下文中探索这一概念。一个简短的视频解释了该功能,点击这里观看。本文面向产品负责人、UX 设计师和移动开发人员。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

背景

自然语言接口和图形用户界面(GUIs)将人类用户与计算机系统的能力连接起来。自然语言允许人们在即时性之外交流,而指点允许对世界上具体事物进行沟通。指点相对于产生和处理自然语言来说,要求对方的认知努力更少,也减少了混淆的可能。然而,自然语言可以传达关于整个世界的信息:具体的、抽象的、过去的、现在的、未来的,以及元世界,提供对一切的随机访问。

随着 ChatGPT 的兴起,自然语言处理(NLP)的解读质量已达到了高水平,利用‘功能调用’,现在可以创建完整的自然语言接口,减少误解的发生。当前 LLM 社区的趋势集中在聊天界面作为主要的对话用户界面。这种方法源于聊天是书面的人际交互的主要形式,并在滚动窗口中保留对话历史。许多信息适合图形表示。一种常见的方法是将 GUI 元素融入聊天对话中。然而,这样的成本是聊天历史变得庞大,并且在聊天历史中管理 GUI 元素的状态是复杂的。此外,通过完全采用聊天范式,我们失去了向用户提供菜单驱动交互路径的选项,使他们在应用程序的功能方面更加模糊。

这里采用的方法可以应用于各种应用程序,例如银行、购物和旅行应用。移动应用的最重要功能位于主屏幕上,但其他选项卡或菜单中的功能可能让用户很难找到。当用户可以用自己的语言表达请求时,他们自然会被引导到最有可能满足需求的屏幕上。当最重要的功能在主屏幕上时,针对这一核心功能的可选项数量可能会使人不知所措。自然语言从另一端接近这一点:用户主动表达他们想要的内容。将这两者结合起来,可以实现最佳状态,即两者互补,用户可以选择最适合其任务或子任务的选项。

自然语言条

自然语言条(NLB)允许用户输入或说出他们想要从应用程序中得到什么。与他们的请求一起,所有屏幕的定义都通过 OpenAI 创造的“函数调用”技术发送到 LLM。在我们的概念中,我们将 GUI 屏幕视为应用程序中的一个函数,其中屏幕上的用户输入小部件被视为该函数的参数。

我们将以银行应用程序为例来说明这一概念。当用户用自然语言发出请求时,LLM 会告诉我们应用中的导航组件打开哪个屏幕以及设置哪些值。这在以下图中进行了说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下图像提供了一些交互示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下图像展示了 LLM 得出的结论。它得出的最佳方式是展示您附近的银行网点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下示例展示了即使显著缩短的表达也可能达到用户期望的结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,自由输入也可以是一种非常快速的交互模式。这种缩略语的正确解释取决于其背后意图的明确性。在这种情况下,应用程序没有其他屏幕可以转移,因此 LLM 可以做出明确的决定。

另一个额外功能是交互有历史记录,因此用户可以继续输入以纠正之前的意图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,LLM 可以结合几条消息,其中一条纠正或增强另一条,以产生所需的函数调用。这对于旅行规划应用程序非常方便,用户最初只提到出发地和目的地,然后在后续消息中添加额外的要求,如日期、时间、仅直达连接、仅头等舱等。

点击这里亲自尝试示例应用程序。语音输入在 Chrome 浏览器以及 Android 和 iOS 本地环境中有效。使用的是平台提供的语音识别,因此如果质量不足以满足您的目的,还有改进的空间。

工作原理

当用户在自然语言栏中提出问题时,会向 LLM 的提示中添加一个JSON 模式。JSON 模式定义了所有屏幕及其输入元素的结构和目的。LLM 尝试将用户的自然语言表达映射到这些屏幕定义中的一个。它返回一个 JSON 对象,以便您的代码可以进行‘函数调用’以激活相应的屏幕。

功能和屏幕之间的对应关系在下图中进行了说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

完整的功能规范可以在这里查看。

自然语言栏的 Flutter 实现基于LangChain Dart,这是 LangChain 生态系统的 Dart 版本。所有提示工程都发生在客户端。将屏幕、导航逻辑和功能模板保存在一起更有意义。由于一对一关系,功能模板被整合到导航结构中。以下展示了激活并导航到信用卡屏幕的代码:

DocumentedGoRoute(
   name: 'creditcard',
   description: 'Show your credit card and maybe perform an action on it',
   parameters: [
     UIParameter(
       name: 'limit',
       description: 'New limit for the card',
       type: 'integer',
     ),
     UIParameter(
       name: 'action',
       description: 'Action to perform on the card',
       enumeration: ['replace', 'cancel'],
     ),
   ],
   pageBuilder: (context, state) {
     return MaterialPage(
         fullscreenDialog: true,
         child: LangBarWrapper(
             body: CreditCardScreen(
                 label: 'Credit Card',
                 action: ActionOnCard.fromString(
                     state.uri.queryParameters['action']),
                 limit:
                     int.tryParse(state.uri.queryParameters['limit'] ?? ''))));
   }),

在顶部,我们看到这是一个路由:应用程序路由系统中的一个目标,可以通过超链接激活。描述部分是 LLM 用来将屏幕与用户意图匹配的部分。下面的参数(信用卡额度和要采取的操作)定义了自然语言中的屏幕字段,以便 LLM 可以从用户的问题中提取这些字段。然后,pageBuilder-item 决定如何使用深层链接的查询参数来激活屏幕。可以在langbar-1d3b9.web.app/home中识别这些参数:在 NLB 中输入‘信用卡额度为 10000’,浏览器的地址栏将显示:langbar-1d3b9.web.app/creditcard?limit=10000

使用了 LangChain 代理,这使得这种方法独立于 GPT,因此也可以使用其他 LLM 如 Llama、Gemini、Falcon 等。此方法还便于添加基于 LLM 的辅助功能。

历史面板

自然语言栏提供了一个可折叠的互动历史面板,用户可以轻松重复以前的陈述。这样,互动历史会被保存,类似于聊天界面,但以紧凑、可折叠的形式出现,节省屏幕空间并防止混乱。用户之前的语言陈述会以用户使用的语言显示。系统响应会作为超链接包含在用户陈述中,可以点击以重新激活对应的屏幕:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当 LLM 无法完全确定要激活的屏幕时,系统响应会被明确显示,此时历史面板会自动展开。这种情况可能发生在用户提供的信息过少、用户的请求超出应用程序的范围,或发生错误时:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

未来

历史面板是提供客户支持和上下文敏感帮助的绝佳场所,采用聊天机器人形式。写作时,有关 RAG(检索增强生成)技术的讨论和演变非常活跃,这些技术使聊天机器人能够根据贵组织提供的大量文本内容回答用户的问题。此外,自然语言栏是想象如何利用自然语言赋予应用程序更多力量和便捷的良好起点。

客户支持

互动的历史面板是嵌入客户支持对话的好地方。这些对话占用的垂直空间比文本中大多数示例更多。在客户支持对话中,贵组织的回答是语言表达,无论是由聊天机器人还是人工服务人员生成。它们需要完全显示,而不是嵌入超链接中。但这没关系,因为否则这些空间会被其他地方占用。贵组织可能已经在网站或应用程序上拥有一个聊天机器人。将其与自然语言栏的历史面板统一是合乎逻辑的。

上下文敏感的帮助

在上述描述的背景下,我们保持与应用程序的语言互动历史。未来,我们可能(隐形地)将直接用户交互的轨迹添加到该历史序列中。通过将用户交互的历史轨迹与 RAG 结合在应用程序的帮助文档中,可以提供上下文敏感的帮助。用户的问题将更能根据应用程序当前状态得到回答。

超越移动应用程序的静态辅助

当前提议是一个 MVP(最简可行产品)。它提供了一个静态模板,用于在应用程序的上下文中解释用户的语言请求。这种技术为未来的广泛改进打开了广阔的前景:

  • 当用户在特定屏幕上提问时,我们可能能够动态地将更多具体的解释模板(功能)添加到提示中,这些模板依赖于该屏幕的状态,例如‘为什么提交按钮变灰/禁用?’。

  • 使用自然语言栏进行功能调用可以作为创意应用的助手,例如执行像‘调整为相同大小’或‘转变为可重用组件’这样的操作。微软 Copilot 365 已经在使用类似的功能。本文中采用的方法也可以帮助您的组织利用这些功能。

与系统每个方面的自然语言交互将迅速成为每个 UI 的主要组成部分。在使用‘功能调用’时,您必须在提示中包含系统能力,但很快会有更经济和更强大的方法上市。例如,OpenAI 最近开放了模型微调与功能调用,允许您创建一个具有系统能力的 LLM 版本。即使这些能力非常广泛,提示的负担仍然有限。

结论

LLMs 可以通过‘功能调用’成为与基于 GUI 的应用程序进行自然语言交互的绝佳桥梁。引入了一个自然语言栏,允许用户输入或说出他们的意图。系统将通过导航到正确的屏幕并预填正确的值来回应。示例应用程序使您实际体验到这一点,提供的源代码使得如果您使用 Flutter,可以快速将其应用到自己的应用程序中。自然语言栏不仅适用于 Flutter 或移动应用程序,还可以应用于任何具有 GUI 的应用程序。它的最大优势是可以从一个单一的访问点打开应用程序的全部功能,而无需用户知道如何操作、在哪里找到功能,甚至不需要了解应用程序的术语。从应用开发的角度来看,您只需简单地记录屏幕的目的和屏幕上的输入小部件,就可以向用户提供这一切。

请在评论中分享您的想法。我非常好奇。

请在LinkedInUXX.AI上关注我。

特别感谢David Miguel Lozano帮助我完成LangChain Dart

一些有趣的文章:多模态对话谷歌关于 GUI 和 LLM 的博客将 GUI 交互解释为语言LLM 驱动的助手语言与 GUI聊天机器人与 GUI

除非另有说明,本文中的所有图片均由作者提供

SynthDiD 101:Synthetic Difference-in-Differences 初学者指南

原文:towardsdatascience.com/synthdid-101-a-beginners-guide-to-synthetic-difference-in-differences-84fed9b730ae

关于该方法的优缺点,使用 R 中的 synthdid 包进行演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Nazlı Alagöz

·发表于 Towards Data Science ·阅读时间 8 分钟·2023 年 4 月 26 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由作者使用Nightcafe生成的标题图像

在这篇博客文章中,我简要介绍了 Synthetic Difference-in-Differences(SynthDiD)方法,并讨论了它与传统的 Difference-in-Differences(DiD)和 Synthetic Control Method(SCM)的关系。SynthDiD 是 SCM 和 DiD 的一个概括版本,结合了两种方法的优势。它可以在大面板数据下进行因果推断,即使在短期的前处理期间也能有效。我讨论了这种方法的优缺点,并使用 R 中的synthdi包演示了这种方法。我提供了简要的要点介绍。

Synthetic Control Method 与 Synthetic Difference-in-Differences

Synthetic Control Method 和 Synthetic Difference-in-Differences 方法紧密相关,但在估计因果效应的方式上有所不同。Synthetic Control Method 是一种统计技术,通过结合多个与处理单元在所有相关特征上相似的对照单元,创建一个“合成”的对照组。合成对照组的构建旨在尽可能接近处理单元的前处理结果。然后,通过将处理单元的后处理结果与合成对照组的结果进行比较,来估计处理效应。

另一方面,合成 DiD 结合了合成控制方法和差分中的差分方法[1]。在这种方法中,使用与合成控制方法相同的方法构建一个合成控制组。然而,通过比较处理单位和合成控制组在处理前后结果的变化来估计处理效果。这种方法通过考虑处理组和控制组之间的先前差异来允许对处理效果进行更稳健的估计。

总结来说,尽管两种方法都使用合成控制组,但合成控制方法通过比较处理单位和合成控制组的后处理结果来估计处理效果,而合成 DiD 通过比较处理单位和合成控制组在引入处理前后的结果变化来估计处理效果。

合成 DiD 的要点:

  • SynthDiD 是 SCM 和 DiD 的广义版本。

  • 它借鉴了 DiD 方法和合成控制方法的优点[2][3]。

  • 它通过最优加权控制组单位来构建处理组的反事实,以最小化处理组和控制组在处理前阶段的差异,就像在 SCM 中一样。

  • 然后,通过比较处理单位和合成控制组在干预前后结果的变化来估计处理效果,就像在 DiD 方法中一样。

  • SynthDiD 考虑了单位级别的结果变化,就像 DiD 方法一样[4]。

  • 即使在处理阶段很短的情况下,它也能在广泛的面板数据中进行推断,这使其与合成控制方法有所区别(SCM 需要较长的处理阶段)。

  • 与 SCM 相同,单位变成了“变量”,我们将结果表示为单位的加权平均值(即,合成控制)。

示例

假设我们是一家销售植物性食品产品的公司,例如豆奶或豆酸奶,我们在多个国家运营。一些国家实施了新法规,禁止我们将植物性产品标记为“牛奶”或“酸奶”,因为声明只有动物产品可以被标记为“牛奶”或“酸奶”(感谢我的一位前学生提供这个示例的灵感 😃。因此,由于这些国家的新规定,我们必须将豆奶标记为豆饮料,而不是豆奶等。我们想知道这项立法对我们收入的影响,因为这可能有助于指导我们在不同国家的游说和营销活动。

我模拟了一个平衡的面板数据集,显示了我们公司在 30 个不同国家 30 个时期的收入。三个国家在 20 期实施了这项立法。下图中可以看到数据的快照。treat是一个虚拟变量,指示一个国家是否在给定时期实施了立法。revenue是以百万欧元计的收入。你可以在这个 Gist中找到模拟和估计代码。

# Install and load the required packages
# devtools::install_github("synth-inference/synthdid")
library(synthdid)
library(ggplot2)
library(data.table)

# Set seed for reproducibility
set.seed(12345)

source('sim_data.R') # Import simulation function and some utilities

dt <- sim_data()
head(dt)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据快照,图片由作者提供。

接下来,我们将面板数据转换为synthdid包所需的矩阵。给定结果、处理和对照单元以及处理前期,创建一个合成对照,并使用synthdid_estimate函数估计治疗效果。为了进行推断,我们还需要计算标准误差。如果有多个处理单元,我使用jacknife方法。如果只有一个处理单元,placebo方法是唯一的选择。根据标准误差,我还计算了治疗效果的 95%置信区间。我将在下图中报告这些结果。

# Convert the data into a matrix
setup = panel.matrices(dt, unit = 'country', time = 'period', 
                       outcome = 'revenue', treatment = 'treat')

# Estimate treatment effect using SynthDiD
tau.hat = synthdid_estimate(setup$Y, setup$N0, setup$T0)

# Calculate standard errors 
se = sqrt(vcov(tau.hat, method='jackknife'))
te_est <- sprintf('Point estimate for the treatment effect: %1.2f', tau.hat)
CI <- sprintf('95%% CI (%1.2f, %1.2f)', tau.hat - 1.96 * se, tau.hat + 1.96 * se)\

我们还将结果绘制一些附加数据。

# Check the number of treatment and control countries to report
num_treated <- length(unique(dt[treat==1]$country))
num_control <- length(unique(dt$country))-num_treated

# Create spaghetti plot with top 10 control units
top.controls = synthdid_controls(tau.hat)[1:10, , drop=FALSE]
plot(tau.hat, spaghetti.units=rownames(top.controls),
     trajectory.linetype = 1, line.width=.75, 
     trajectory.alpha=.9, effect.alpha=.9,
     diagram.alpha=1, onset.alpha=.9, ci.alpha = .3, spaghetti.line.alpha =.2,
     spaghetti.label.alpha = .1, overlay = 1) + 
  labs(x = 'Period', y = 'Revenue', title = 'Estimation Results', 
       subtitle = paste0(te_est, ', ', CI, '.'), 
       caption = paste0('The number of treatment and control units: ', num_treated, ' and ', num_control, '.'))

在下图中,展示了估计结果。观察治疗国家和合成对照的平均趋势如何相对平行(它可能看起来不完全平行,但对于本示例而言并不必要)。治疗国家的平均值变动较大,主要由于只有三个这样的国家,导致趋势不够平滑。透明的灰色线条代表不同的对照国家。自 20 期的处理开始后,治疗国家的收入下降,估计为 0.51 百万欧元,如图所示。这意味着新法规对我们公司的收入有负面影响,应采取必要措施以防止进一步下降。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果,图片由作者提供。

让我们绘制用于估计合成对照的权重。

# Plot control unit contributions
synthdid_units_plot(tau.hat, se.method='jackknife') +
  labs(x = 'Country', y = 'Treatment effect', 
       caption = 'The black horizontal line shows the actual effect; 
       the gray ones show the endpoints of a 95% confidence interval.')

在下图中,你可以观察到每个国家在构建合成对照时的加权情况。治疗效果根据选定的未处理国家作为对照单元有所不同。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

国家权重,图片由作者提供。

现在我们对 SynthDiD 有了更多的了解,接下来讨论一下这种方法的优缺点。每种方法都有其优缺点,SynthDiD 也不例外。以下是开始使用这种方法时需要注意的一些优缺点。

SynthDiD 方法的优点:

  • 合成控制方法通常用于少量处理和控制单位,并且需要处理前的长期平衡数据。而 SynthDiD,即使在处理前的数据周期较短的情况下也能很好地工作,这与合成控制方法不同[4]。

  • 该方法之所以被优先考虑,特别是因为它不像 DiD 那样有严格的平行趋势假设(PTA)要求。

  • SynthDiD 保证了控制单位的适当数量,考虑了可能的干预前模式,并可能容纳一定程度的内生处理时机[4]。

SynthDiD 方法的缺点:

  • 计算可能比较昂贵(即使只有一个处理组/区块)。

  • 需要一个平衡面板(即,你只能使用在所有时间段都被观察到的单位),并且处理时机对所有处理单位是相同的。

  • 需要足够的处理前时间段以获得良好的估计,因此,如果没有足够的处理前时间段,可能更适合使用普通的 DiD。

  • 计算和比较子组的平均处理效应很棘手。一个选择是将样本拆分为子组,并计算每个子组的平均处理效应。

  • 实施 SynthDiD 时,如果处理时机各不相同,可能会很棘手。对于错峰处理时机,可以考虑为每个处理队列估计平均处理效应,然后将队列特定的平均处理效应汇总为总体平均处理效应。

这里还有一些其他你可能想知道的起步时要点。

需要注意的事项:

  • SynthDiD 采用正则化岭回归(L2),同时确保结果权重的总和为 1。

  • 在处理前匹配的过程中,SynthDiD 尝试确定整个样本的平均处理效应。这种方法可能会导致个别时间段的估计不够精确。然而,总体平均值能提供一个无偏的评估。

  • 处理效应的标准误差是通过抛弃法(jacknife)估计的,或者如果一个队列只有一个处理单位,则使用安慰剂方法。

  • 估计量被认为是一致且渐近正态的,前提是控制单位数量和处理前时间段的组合相对于处理单位数量和处理后时间段的组合足够大。

  • 在实践中,处理前变量在合成 DiD 中作用较小,因为滞后结果具有更强的预测能力,使得这些变量的处理不那么重要。

结论

在这篇博客文章中,我介绍了 SynthDiD 方法,并讨论了它与传统 DiD 和 SCM 的关系。SynthDiD 结合了 SCM 和 DiD 的优势,即使在处理期较短的情况下也能进行因果推断。我使用 R 中的 synthdid 包来演示该方法。尽管它有几个优点,比如不需要严格的平行趋势假设,但也有缺点,如计算开销大且需要平衡面板。总体而言,SynthDiD 是一个对有兴趣使用观察数据估计因果效应的研究人员非常有价值的工具,为传统的 DiD 和 SCM 方法提供了替代方案。

参考文献

[1] D. Arkhangelsky, S. Athey, D.A. Hirshberg, G.W. Imbens, 和 S. Wager, 合成差分法 (2021),美国经济评论

[2] A. Abadie, A. Diamond, J. Hainmueller, 比较案例研究的合成控制方法:估计加州烟草控制计划的效果 (2010),美国统计协会杂志

[3] A. Abadie, 使用合成控制:可行性、数据要求和方法论方面 (2021),经济学视角杂志

[4] Berman, R., & Israeli, A., 描述性分析的价值:来自在线零售商的证据 (2022),营销科学

有用的链接

勇敢和真实的因果推断,合成差分法。

Matteo Courthhoud, 了解合成控制方法。

感谢阅读!

如果你喜欢这篇文章并希望看到更多我的文章,可以考虑 关注我

免责声明:我写作是为了学习,因此你可能会在文章或代码中发现错误。如果发现,请告知我。

合成控制:如果我们可以模拟替代现实呢?

原文:towardsdatascience.com/synthetic-control-what-if-we-could-simulate-alternate-realities-4e88eb69d7b9

一种更好的政策评估方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 布鲁诺·波内

·发表于 Towards Data Science ·6 分钟阅读·2023 年 6 月 10 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Hubert Buratynski 提供,来源于 Unsplash

看哪,看那边

太阳已经消失的地方

《莫比 — 最后一日》

当我在高中时,我清楚地记得问我的历史老师:“如果罗马帝国没有崩溃,我们今天的技术会有多先进?”她并不特别欣赏我的问题。事实上,历史学家往往对“如果”问题持保留态度,有时称之为反事实历史。他们更喜欢解释和说明事件的发生,而不是可能发生的情况。他们的工作基于事实、来源和证据,而“如果”场景可能会导致猜测或推测,影响对历史现实的严谨分析。

作为一个青少年时期的内省梦想者,我不断想象如果我们没有经历中世纪,会发生什么。实证科学是否会更早发展?几个世纪以来,战争是否会更频繁发生?我们是否会更好地照顾我们的星球?

这样的问题依然开放,因为一旦发展发生,就不可能经历一个没有发生该发展的替代现实。这本质上是因果推断的基本问题,即研究因果关系的科学。例如,如果政府决定实施禁止饮酒的政策,这是否会导致车祸死亡率的下降?理想情况下,这个因果关系问题应通过比较在没有禁令的实际世界与只有政策实施的平行世界中的车祸死亡率来回答。在这个理想的场景中,政策的影响将是观察到的无政策死亡率与有政策死亡率之间的差异。显然,这并不可行,因为我们只能访问我们自己的现实。

激励市长是否能改善教育?

我一直对教育和公共政策的动态感兴趣,特别是它们如何相互作用来塑造社会的未来。当选择硕士论文的主题时,我希望探讨一个相关、具有影响力并且有现实世界影响的课题。我想深入探讨一个可能为改善巴西教育系统提供见解的主题,不仅在理论上,而且在实践中也是如此。正是在这个过程中,我发现了巴西塞阿拉州实施的两个有趣的教育政策。

第一个政策是对市长的税收激励(TI),以改善市政教育。这是一种创新的方法,将市政税收转移与教育成就挂钩,鼓励地方政府更多地投资于教育系统。第二个政策是向市政府提供教育技术援助(TA)的项目,为他们提供改善教育实践所需的资源。

一些描述性图表显示,尽管塞阿拉州的资源投入较少,但相较于其他州其表现有所提升,如下图所示。纵轴展示了学生在数学和葡萄牙语测试中的正面分数变化,而横轴则显示了教育平均支出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:Ponne, B. G. (2023)¹

为确保政策确实导致了这些改善,我需要更深入地分析这些政策,再次遇到了因果推断的基本问题:如果塞阿拉州没有采取这些政策,会怎样?他们的教育指标会更差吗?换句话说,这些政策是否对教育成就产生了积极影响?我没有一个完美的反事实,一个政策未被采纳的替代塞阿拉州。幸运的是,因果推断提供了一些近似反事实的方法。其中之一是合成控制法。

合成控制法

合成控制方法是一种统计技术,主要用于评估政策变化或其他干预措施的效果,当没有对照组时使用。其原理是通过结合未经历政策变化的多个州,创建一个感兴趣单位(在本例中为塞阿拉州)的合成版本。这个“合成控制”作为对照——它是我们期望在没有实施政策的情况下,感兴趣单位会发生的情况。

为了构建这个合成控制,我们必须选择一组未受到政策影响的州——这些州通常称为捐赠单位。然后,合成控制作为这些捐赠单位的加权组合创建,选择的方式是使合成控制与处理单位(塞阿拉州)干预前的特征紧密匹配。实际上,合成控制代表了一个没有采纳教育政策的假设性塞阿拉州。这种解释只是概述了该方法的基本概念。要更全面地理解,请参阅 Alberto Abadie(2021)²的《使用合成控制:可行性、数据要求和方法论方面》。

一旦建立了合成控制,我们就比较处理单位(塞阿拉州)及其合成对照组的干预后结果。这两者之间的差异可以解释为干预或政策的效果。

在下面的图表中,我描绘了塞阿拉州及其人工构建的未受政策影响的塞阿拉州的数学和葡萄牙语分数趋势。请注意,在政策实施之前,合成趋势与实际趋势非常接近,但之后明显分歧。根据这种方法,在没有政策的情况下,塞阿拉州的分数将遵循黄色线所代表的轨迹。在政策影响下,塞阿拉州的实际分数由绿色线表示。这两条线之间的差异表明这些政策的积极效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

两项政策的结合导致了葡萄牙语测试分数在小学教育中稳定提高了 12%,在初中教育中提高了 6.5%。这些结果表明,精心设计的政策可能对教育成果产生重大影响。数学领域的结果并没有统计学意义。在我发表的论文¹中,我提供了一些解释为什么会发生这种情况。

然而,我的分析也揭示了一个关注点。尽管在初级和中级教育方面取得了这些进展,但上级中学虽然没有直接受到新政策的影响,但却接收到了来自低年级的更好准备的学生,却没有显著改善。这一发现突显了政策实施中的关键缺口,并引发了对将教育政策的好处扩展到上级中学以及其他巴西州的进一步讨论的需求。

R 中的合成控制方法

我使用了R synth library来实现合成控制。这个库是 R 中估计合成控制的一个非常强大的工具。它提供了两个主要功能:

  • dataprep(): 准备捐赠池和处理单元特征的矩阵以及它们的感兴趣结果。这些矩阵随后可以传递给synth()

  • synth(): 优化权重集以形成合成单元。

这个包还提供了在基础 R 中绘制结果的函数,但你也可以像我上面做的那样,准备由synth()交付的数据以便在 ggplot2 中绘制。查看代码:github.com/bruno-ponne/Better-Incentives-Better-Marks

最后的思考

合成控制方法为我提供了一个独特的机会来研究这些政策对塞阿拉州教育成就的因果影响,为“如果”问题提供了定量维度。通过这种方法,我的研究超越了理论推测的领域,使基于数据和统计方法的严格分析成为可能。

我一直相信教育是促进发展中国家宽容、机会和民主的关键因素。使用合成控制的方法揭示了精心设计的政策在显著改善教育成果方面的潜力。我希望这些发现能为政策制定者提供有价值的见解,以便做出明智的教育决策。

引用的文章:

¹Ponne, B. G. (2023). 更好的激励,更好的成绩:对巴西塞阿拉州教育政策的合成控制评估。巴西政治科学评论17(1),e0005。 doi.org/10.1590/1981-3821202300010005

²Abadie, Alberto (2021), 使用合成控制:可行性、数据要求和方法学方面。经济文献杂志。59(2),第 391–425 页。

系统设计备忘单:ElasticSearch

原文:towardsdatascience.com/system-design-cheatsheets-elasticsearch-673b98eebfff?source=collection_archive---------0-----------------------#2023-11-28

了解如何以及何时在系统中使用 ElasticSearch,并通过三个实际的系统设计示例进行说明

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Sanil Khurana

·

关注 发表在 Towards Data Science ·13 分钟阅读·2023 年 11 月 28 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

引言

什么是搜索?它为何重要?

如果你阅读过我之前关于搜索的文章,你会知道搜索对于应用程序的重要性。想一想:在你每天使用的各种网络应用和移动应用中,无论是 Netflix、Amazon 还是 Swiggy,搜索框可能是唯一一个在所有这些应用中都存在的通用 UI 元素,而且它通常都位于主页的顶部。如果你在设计一个系统,十有九九,你会考虑如何支持搜索功能。

建立一个搜索系统不是小事,但一个很好的起点是 ElasticSearch。如果你对搜索或推荐系统的工作原理一无所知,这篇博客文章是一个很好的起点。我们将讨论 ElasticSearch 是什么,它的适用场景和不适用场景,以及 ElasticSearch 常见的三种设计。搜索系统还有很多其他属性,但这些内容将在文章的后面详细讨论。

什么是 ElasticSearch?

ElasticSearch 是一个流行的数据库,它处理的是大多数数据库难以应对的任务:搜索。搜索对于 ElasticSearch 来说至关重要,它甚至体现在它的名字里!

但是如果你还没有听说过 ElasticSearch,你可能会想:为什么搜索这么困难?为什么关系型数据库无法进行搜索?大多数关系型数据库支持多种搜索和过滤数据的方法,比如 WHERE 查询、LIKE 关键字或索引。或者为什么像 MongoDB 这样的文档数据库无法工作?你也可以在 MongoDB 中编写 find 查询。

要理解这个答案,想象你正在建立一个新闻网站。当用户使用你的搜索框搜索新闻时,例如“新德里 COVID19 感染”,用户对所有 讨论 新德里 COVID 感染的文章感兴趣。在一个简单的搜索系统中,这意味着扫描数据库中的所有文章,并返回那些包含“COVID19”、“感染”或“新德里”这些词的文章。你不能用关系型数据库做到这一点。关系型数据库允许你基于特定属性搜索文章,比如特定作者撰写的文章或今天发布的文章等,但它不能(至少不能高效地)执行一个扫描 每一篇 新闻文章(通常是数千万篇)并返回那些包含特定单词的搜索。

此外,还有许多复杂的细节需要考虑。你如何对这些文章进行评分?也许有一篇文章讨论了 COVID19 的传播,也许有一篇讨论了新感染,你如何知道哪一篇与用户查询更相关,换句话说,你如何根据相关性对这些文章进行排序?

答案是:ElasticSearch!ElasticSearch 可以立即提供所有这些功能和更多。

但是,和世界上其他一切事物一样,它也有其自身的缺点。让我们来探讨一下 ElasticSearch 是什么,什么时候使用它,最重要的是,什么时候不适合使用它。

ElasticSearch

搜索能力

ElasticSearch 提供了一种执行“全文搜索”的方法。全文搜索指的是在大量文档中搜索一个短语或单词。继续我们之前的例子,假设你正在构建一个包含数百万篇新闻文章的新闻网站。每篇文章包含一些数据,比如标题、副标题、文章内容、发布时间等。在 ElasticSearch 的上下文中,每篇文章被存储为一个 JSON 文档。

你可以将所有这些文档加载到 ElasticSearch 中,然后在几毫秒内搜索每个文档中的特定单词或短语。因此,如果你加载所有新闻文章,然后执行一个搜索,比如“COVID19 感染在德里”,ElasticSearch 会返回所有包含“COVID19”、“感染”或“德里”这些词的文章。

为了演示在 ElasticSearch 中的搜索,我们来设置 Elasticsearch 并加载一些数据。对于本文,我将使用我在 Kaggle 上找到的这个新闻数据集(Misra, Rishabh. “News Category Dataset.” arXiv 预印本 arXiv:2209.11429 (2022)) (来源) (许可证)。该数据集非常简单,包含约 210,000 篇新闻文章,涵盖标题、简短描述、作者以及一些我们不太关注的其他字段。我们并不需要所有 210,000 篇文档,因此我会加载大约 10,000 篇文档到 ES 中并开始搜索。

这些是数据集中一些文档的示例——

[
  {
    "link": "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",
    "headline": "Why New York City’s Board Of Elections Is A Mess",
    "short_description": "“There’s a fundamental problem having partisan boards of elections,” said a New York elections attorney.",
    "category": "POLITICS",
    "authors": "Daniel Marans",
    "country": "IN",
    "timestamp": 1689878099
  },
  ....
]

每个文档代表一篇新闻文章。每篇文章包含一个 linkheadline、一个 short_description、一个 categoryauthorscountry(随机值,由我添加)和 timestamp(同样是随机值,由我添加)。

Elasticsearch 查询是用 JSON 编写的。在深入探讨所有不同的语法之前,我们先从简单的开始,逐步构建。

最简单的全文查询之一是 multi_match 查询(不用太担心在 ElasticSearch 中查询数据,它非常简单,我们将在文章末尾讨论)。其思想很简单,你编写一个查询,Elasticsearch 执行全文搜索,实质上扫描你数据库中的所有文档,找到包含查询中单词的文档,给它们分配一个评分,并返回这些文档。例如,

GET news/_search
{
  "query": {
    "multi_match": {
      "query": "COVID19 infections"
    }
  }
}

上述查询找到了与“COVID19 感染”相关的文章。这些是我得到的结果 -

 [
      {
        "_index" : "news",
        "_id" : "czrouIsBC1dvdsZHkGkd",
        "_score" : 8.842152,
        "_source" : {
          "link" : "https://www.huffpost.com/entry/china-shanghai-lockdown-coronavirus_n_62599aa1e4b0723f8018b9c2",
          "headline" : "Strict Coronavirus Shutdowns In China Continue As Infections Rise",
          "short_description" : "Access to Guangzhou, an industrial center of 19 million people near Hong Kong, was suspended this week.",
          "category" : "WORLD NEWS",
          "authors" : "Joe McDonald, AP",
          "country" : "IN",
          "timestamp" : 1695106458
        }
      },
      {
        "_index" : "news",
        "_id" : "ODrouIsBC1dvdsZHlmoc",
        "_score" : 8.064016,
        "_source" : {
          "link" : "https://www.huffpost.com/entry/who-covid-19-pandemic-report_n_6228912fe4b07e948aed68f9",
          "headline" : "COVID-19 Cases, Deaths Continue To Drop Globally, WHO Says",
          "short_description" : "The World Health Organization said new infections declined by 5 percent in the last week, continuing the downward trend in COVID-19 infections globally.",
          "category" : "WORLD NEWS",
          "authors" : "",
          "country" : "US",
          "timestamp" : 1695263499
        }
      },
      ....
]

正如你所见,它返回了讨论 COVID19 感染的文档。它还按相关性顺序对这些文档进行排序(_score 字段表示特定文档的相关性)。

ElasticSearch 具有丰富的查询语言和大量功能,但目前只需知道构建一个简单的搜索系统非常容易,只需将所有数据加载到 ElasticSearch 中,并使用我们讨论过的简单查询即可。我们有许多选项可以改进、配置和调整搜索性能和相关性(关于搜索查询的更多内容将在本文末尾讨论)。

分布式架构

ElasticSearch 作为分布式数据库工作。这意味着在一个 ElasticSearch 集群中有多个节点。如果一个节点变得不可用或失败,这通常不会导致系统停机,其他节点通常会接管额外的工作并继续服务用户请求。因此,多个节点有助于提高可用性。

多个节点还帮助我们扩展系统,数据和用户请求可以在这些节点之间划分,从而减少每个节点的负载。例如,如果你想在 ElasticSearch 中存储 1 亿篇新闻文章,你可以将这些数据分割到多个节点上,每个节点存储一部分文章。实际上,这非常简单,ElasticSearch 提供了内置功能来使这一过程尽可能简单和无缝。

扩展性

ElasticSearch 横向扩展,能够将数据分区到多个节点。这意味着你可以通过增加更多节点来始终提高查询性能。

关于架构你的 ElasticSearch 集群,思考的过程远不止于增加更多服务器。不同类型的节点运行着称为“shards”的进程,每个 shard、节点,可以有多种类型和配置选项。关于 ElasticSearch 集群的架构及其工作原理有很多内容可以讨论,如果你想更深入了解,可以查看我写的完整文章 这里

总结:你可以添加更多机器来扩展你的集群并提高性能。数据和查询会被分配到多个机器上,这有助于提高性能和扩展性。

基于文档的数据建模

ElasticSearch 是一个文档数据库,它以 JSON 文档格式存储数据,类似于 MongoDB。因此,在我们的例子中,每篇新闻文章都作为 JSON 文档存储在集群中。

实时数据分析

实时数据分析是实时查看用户行为并了解用户模式和行为。我们可以绘制用户行为图表,更好地理解我们的用户,从而改进我们的产品。例如,假设我们测量每个用户在新闻网站上的每一次点击、滚动事件和阅读时间。我们将这些指标绘制在仪表板上并观察几天。通过这些数据,我们可以收集大量可操作的见解来改进我们的新闻应用。我们发现用户通常在早上 9-10 点使用网站,并且发现用户通常点击与他们国家相关的文章。利用这些信息,我们可以在高峰期(早上 9-10 点)超配资源,并可能在用户的首页上显示来自他们国家的文章。

Elasticsearch 由于其分布式架构和强大的搜索能力,非常适合实时数据分析。当处理实时数据时,如日志、指标或社交媒体更新,Elasticsearch 能高效地索引和存储这些信息。它的近实时索引使得数据在摄取后几乎可以立即被搜索。Elasticsearch 还可以很好地与其他工具配合使用,如用于可视化的 Kibana 或用于收集指标的 Logstash 和 Beats。

在文章的末尾,我们将探讨一种有助于实现这一点的架构。

成本

ElasticSearch 的运行和维护成本很高。正如世上所有美好事物都需付出代价一样,为了执行全文搜索,ElasticSearch 会在 RAM 中保持大量数据并构建复杂的索引。这意味着它需要大量的 RAM 来运行,这也是一笔不小的开支。

简而言之,ElasticSearch 在执行全文搜索时提供了惊人的性能,但它并不便宜。

什么时候不该使用 ElasticSearch

ACID 合规性

ElasticSearch 像大多数 NoSQL 数据库一样,对 ACID 的支持非常有限,因此如果你需要强一致性或事务支持,ElasticSearch 可能不是适合你的数据库选择。其后果是,如果你在 ElasticSearch 中插入一个文档(称为“索引”一个文档),该文档可能不会立即对其他节点可见,并且可能需要几毫秒才能被其他节点看到。

比如说,你正在构建一个银行系统;如果用户向其账户中存款,你希望这些数据能立即对用户执行的其他交易可见。另一方面,如果你使用 ElasticSearch 为你的新闻网站提供搜索服务,当一篇新文章发布时,文章在前几毫秒内对所有用户不可见可能是可以接受的。

当你需要复杂的联接时

ElasticSearch 不支持 JOIN 操作或不同表之间的关系。如果你习惯使用关系型数据库,这可能会让你感到有些震惊,但大多数 NoSQL 数据库对这些类型的操作支持有限。

如果你需要执行 JOIN 操作或使用外键来处理高度相关的结构化数据,ElasticSearch 可能不是你用例的最佳选择。

小型数据集或简单查询需求

ElasticSearch 复杂且成本高昂。运行和管理大型 ElasticSearch 集群不仅需要软件工程师和 DevOps 工程师的知识和技能,还可能需要擅长管理和架构 ElasticSearch 集群的专家,称为“ElasticSearch 架构师”。有大量的配置选项和架构选择可以尝试,每一个都对你的查询和摄取产生重要影响,从而间接影响系统核心流程中的用户体验。

如果你只需要执行简单的查询或数据量相对较少,那么简单的数据库可能更适合你的应用程序。

如何在系统设计中使用 ElasticSearch

一个单一的软件系统通常需要多个数据库,每个数据库支持不同的功能。让我们通过一个例子来更好地理解使用 ElasticSearch 的设计选择。

假设你想构建一个视频流媒体服务,比如 Netflix。让我们看看 ElasticSearch 在这个例子中可以适应的地方。

作为搜索系统

ElasticSearch 的一个非常常见的用例是作为支持全文搜索查询的辅助数据库。这对我们的在线视频应用非常有用。我们不能将视频存储在 ElasticSearch 中,并且我们可能也不想将与计费或用户相关的数据存储在 ElasticSearch 中。

为此,我们可以使用其他数据库,但我们可以将电影标题、描述、类型、评分等信息存储在 ElasticSearch 中。

我们可以有一个类似这样的架构:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

我们可以将我们希望支持全文搜索的数据摄取到 ElasticSearch 中。当用户执行搜索操作时,我们可以查询 ElasticSearch 集群。这样,我们就可以利用 ElasticSearch 的全文搜索功能,当我们需要更新用户信息时,可以在我们的主要存储中执行这些更新。

作为实时数据分析管道

正如我们讨论的,了解用户行为和模式是决定如何发展产品的关键步骤。我们可以发布事件,例如点击流事件和滚动事件,以更好地理解用户如何使用我们的产品。

例如,在我们的在线视频应用中,我们可以在用户点击电影或节目时发布包含用户和电影数据的事件。然后我们可以分析和绘制汇总图表,以更好地理解用户如何使用我们的产品。例如,我们可能会注意到用户在晚上使用我们的产品的频率比在下午高,或者用户可能更喜欢用本国语言而非其他语言的节目或电影。利用这些信息,我们可以改进我们的产品,提升用户体验。

这就是使用 ElasticSearch 和 Kibana(一个与 ElasticSearch 配合良好的仪表板工具)的实时数据分析基本系统的样子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

作为推荐系统

我们可以在 ElasticSearch 中构建查询,以对某些属性给予更多优先级(称为提升)。例如,与简单查询相比

我们可以使用 ElasticSearch 构建基本的推荐系统。我们可以存储有关用户的信息,例如用户的国家、年龄、偏好等,并生成查询,以获取该用户的热门电影节目或系列。

理解查询语言和如何提升某些字段以及执行汇总是一个较大的主题,但我在这里写了一篇涵盖基础知识的博客文章:

## 掌握 Elasticsearch: 初学者强大的搜索与精准指南 — 第一部分

在第一部分解锁 Elasticsearch 的力量:深入了解 Elasticsearch,掌握基本的搜索查询,并探索词汇…

towardsdatascience.com

结论

如何构建 ElasticSearch 集群?

构建 ElasticSearch 集群绝非易事,它需要了解节点、分片、索引以及如何协调它们。选择几乎是无限的,且领域不断发展(尤其是随着 AI 和 AI 驱动搜索的流行)。为了深入探讨,我写了一篇完整的博客文章,从基础知识到构建搜索集群所需了解的一切:

[## 系统设计系列: ElasticSearch, 搜索架构设计

理解 Elasticsearch 架构和全文搜索

betterprogramming.pub](https://betterprogramming.pub/system-design-series-elasticsearch-architecting-for-search-5d5e61360463?source=post_page-----673b98eebfff--------------------------------)

理解搜索查询并改进搜索系统

搜索是复杂的,非常复杂。有很多方法可以改进搜索系统,使其更强大并更理解用户需求。你已经了解了 ElasticSearch 及其功能。从这里开始,构建一个基本的搜索查询,理解查询和系统中的问题,并通过示例一步一步地演变和改进系统。

## 掌握 Elasticsearch: 初学者强大的搜索与精准指南 — 第一部分

在第一部分解锁 Elasticsearch 的力量:深入了解 Elasticsearch,掌握基本的搜索查询,并探索词汇…

towardsdatascience.com

上下文感知搜索

我最近读到一个很好的搜索系统类比。你可以把我们讨论的搜索系统看作是一个机械而僵化的搜索。当用户输入一个词时,我们找到所有包含该词的文档并返回它们。

或者你可以把搜索系统想象成一个图书管理员。当用户问一个问题,比如“温斯顿·丘吉尔在第二次世界大战中的角色是什么?”,图书管理员不会仅仅告诉他包含“温斯顿”、“丘吉尔”或“第二次世界大战”这些词的书籍。相反,图书管理员会评估和理解客户及其背景。也许是一个小学生,所以她不会推荐一本大教科书,而是找到一本更适合年轻孩子的书。或者她可能没有任何关于温斯顿·丘吉尔的书籍,于是她会找到一本讲述第二次世界大战或英国首相的书籍,并推荐这本书。图书管理员甚至可能会为考试和暑假作业推荐不同的书籍(你们中的一些人可能不知道,但在一些国家,暑假作业量非常大)。

对你我来说这很容易理解,但我们的系统如何知道温斯顿·丘吉尔是英国首相并推荐关于第二次世界大战期间英国的书籍,或者我们的系统如何理解讨论的背景、理解用户并推荐合适的书籍呢?

尽管看起来很困难,但实际上并没有那么难。这叫做语义搜索,它是大多数大型科技公司构建搜索系统的方式。

语义搜索是一组搜索技术,旨在理解用户查询背后的含义和内容的上下文,通过考虑单词之间的关系和搜索意图,从而提供更准确、更相关的搜索结果。

这是一个广泛的话题,我仍在阅读和理解更多内容,但即将发布一篇从基础开始的博客文章,如果你想了解更多这个话题,可以在 Medium 上关注我。

其他数据库

我写关于系统设计概念的文章,例如数据库、队列和发布-订阅系统,所以可以在 Medium 上关注我,获取类似的文章。我还在 LinkedIn 上写了很多简短的内容(例如,这篇文章讲述了 RabbitMQ 和 Kafka 的区别),所以可以在 LinkedIn 上关注我,获取更短的内容形式在这里

同时,你可以查看我关于其他数据库和系统设计概念的博客文章-

[## Sanil Khurana 在 Medium 上策划了一些列表

开始探索 Linux、Cassandra、面试问题等

medium.com](https://medium.com/@sanilkhurana7/lists?source=post_page-----673b98eebfff--------------------------------)

系统设计系列:从零开始构建高性能数据流系统的终极指南!

原文:towardsdatascience.com/system-design-series-0-to-100-guide-to-data-streaming-systems-3dd584bd28fa?source=collection_archive---------0-----------------------#2023-12-17

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Sanil Khurana

·

关注 发表在 Towards Data Science ·12 分钟阅读·2023 年 12 月 17 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:Unsplash

设定一个示例问题:推荐系统

“数据流”听起来非常复杂,而“数据流管道”则更为复杂。在我们讨论这意味着什么并陷入术语之前,让我们从任何软件系统存在的原因——一个问题——开始。

我们的问题非常简单,我们需要为一个电子商务网站(类似于亚马逊)建立一个推荐系统,即一个根据用户偏好返回一组产品的服务。我们暂时不需要为它如何工作而感到疲惫(稍后会详细讨论),现在我们将专注于数据如何发送到这个服务中,以及它如何返回数据。

数据以“事件”的形式发送到服务中。这些事件都是用户执行的特定操作。例如,点击特定产品或搜索查询。简单来说,我们网站上所有的用户互动,从简单的滚动到昂贵的购买,都被视为一个“事件”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:作者

这些事件本质上告诉我们有关用户的信息。例如,一个有意购买游戏 PC 的用户可能也会对游戏键盘或鼠标感兴趣。

我们的服务不时会收到获取用户推荐的请求,它的工作很简单,响应用户感兴趣的产品列表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:作者

目前,我们不关心这些推荐列表是如何生成的,假设这个“推荐服务”执行了一些神奇的步骤(关于这些魔法的更多内容将在文章末尾讨论,现在我们不太关心这些步骤的逻辑),并找出用户的偏好。

推荐在许多系统中通常是事后的考虑,但它比你想象的要重要得多。几乎你使用的每个应用程序都依赖于像这样的推荐服务来驱动用户行为。例如,根据这篇论文,35%的亚马逊网络销售是通过推荐商品生成的。

然而,问题在于数据的巨大规模。即使我们运行的是一个中等流行的网站,在高峰时段,我们仍可能每秒接收到数十万(甚至可能是百万)个事件!如果有新产品或大型促销活动,那么这个数量可能会更高。

但我们面临的问题不仅仅如此。我们必须实时处理这些数据(执行之前讨论的魔法),并实时向用户提供推荐!如果有促销活动,即使是几分钟的推荐更新延迟也可能对业务造成重大财务损失。

什么是数据流处理管道?

数据流处理管道就是我上面描述的那样。它是一个接收连续数据(如事件)、执行多个处理步骤并存储结果以备未来使用的系统。

在我们的案例中,事件将来自多个服务,我们的处理步骤将涉及几个“神奇”的步骤来计算用户的推荐,然后我们将在数据存储中更新每个用户的推荐。当我们收到对特定用户推荐的查询时,我们只需获取之前存储的推荐并返回它们。

这篇文章的目的是了解如何处理这种规模的数据,如何摄取、处理和输出这些数据以供以后使用,而不是了解处理步骤的实际逻辑(但我们仍会稍微探讨一下,增加一些趣味)。

创建数据流管道:逐步指南

这涉及到许多方面,如数据摄取、处理、输出和查询,因此我们一步一步来。把每一步看作是一个较小的、孤立的问题。在每一步,我们将从最直观的解决方案开始,看看它为什么不起作用,然后构建一个有效的解决方案。

数据摄取

让我们从管道的起点开始,数据摄取。数据摄取问题相对容易理解,目标只是从多个来源摄取事件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

但虽然问题看起来简单,它也有其复杂的方面,

  1. 数据的规模非常大,轻松达到每秒数十万事件。

  2. 所有这些事件必须实时摄取,我们不能有哪怕几秒钟的延迟。

我们从简单的开始,实现这一目标的最直观方法是将每个事件作为请求发送到推荐系统,但这个解决方案存在许多问题。

  1. 发送事件的服务不应等待我们的推荐服务的响应。这会增加服务的延迟,并在推荐服务发送 200 状态码之前阻塞它们。它们应该改为发送“火并忘”的请求。

  2. 事件的数量会高度波动,一整天都会上下波动(例如,晚上或促销期间会增加),我们需要根据事件的规模来扩展我们的推荐服务。这是我们需要管理和计算的内容。

  3. 如果我们的推荐服务崩溃,我们将会在其停机期间丢失事件。在这种架构中,我们的推荐服务是一个单点故障。

我们可以通过使用消息代理或像 Apache Kafka 这样的“事件流平台”来解决这个问题。如果你不知道这是什么,它简单来说就是一个工具,可以从“发布者”那里接收消息并发布到特定主题上。“订阅者”监听或订阅这些主题,每当在主题上发布消息时,订阅者就会收到消息。我们将在下一节中进一步讨论 Kafka 主题。

你需要了解关于 Kafka 的一点是,它促进了生产者和消费者之间的解耦架构。生产者可以在 Kafka 主题上发布消息,而不需要关心消费者何时、如何或是否消费消息。消费者可以在自己的时间消费消息并处理它。Kafka 也能够实现非常高的扩展,因为它可以水平扩展,并且线性扩展,提供几乎无限的扩展能力(只要我们继续增加更多机器)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

所以每个服务将事件发送到 Apache Kafka。推荐服务从 Kafka 中获取这些事件。让我们看看这对我们有什么帮助 —

  1. 事件是异步处理的,服务不再需要等待推荐服务的响应。

  2. 扩展 Kafka 更加容易,如果事件的规模增加,Kafka 将简单地存储更多事件,同时我们也扩展我们的推荐服务。

  3. 即使推荐服务崩溃,我们也不会丢失任何事件。事件被持久化在 Kafka 中,因此我们不会丢失任何数据。

现在我们知道如何将事件引入我们的服务,让我们转到架构的下一部分——处理事件。

数据处理

数据处理是我们数据管道的一个组成部分。一旦我们接收到事件,我们需要为用户生成新的推荐。例如,如果用户搜索“显示器”,我们需要基于这个搜索更新该用户的推荐,也许会添加用户对显示器感兴趣的信息。

在我们进一步讨论架构之前,让我们忘记这些,稍微谈谈如何生成推荐。这也是机器学习发挥作用的地方,虽然理解这些内容对继续阅读文章并不是非常重要,但它非常有趣,所以我会尝试给出一个非常基础的简要描述。

让我们更好地理解用户互动及其含义。当用户通过搜索、点击或滚动事件与我们的网站互动时,用户是在告诉我们他/她的兴趣。我们的目标是理解这些互动,并利用它们来了解用户。

当你想到一个用户时,你可能会想到一个有姓名、年龄等个人信息的人。然而,为了我们的目的,将每个用户视为一个向量,或者简单地说是一组数字会更容易理解。听起来可能有些令人困惑(毕竟用户怎么能用一组数字来表示呢),但请耐心看下去,我们来看看这是怎么工作的。

假设我们可以将每个用户(或他的/她的兴趣)表示为二维空间中的一个点。每个轴表示用户的一个特征。假设 X 轴表示他/她喜欢旅行的程度,Y 轴表示他/她喜欢摄影的程度。用户的每个行为都会影响这个用户在二维空间中的位置。

假设一个用户在我们的二维空间中从以下点开始 —

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

当用户搜索“旅行包”时,我们将点向右移动,因为这表明用户喜欢旅行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

如果用户搜索了相机,我们将把用户向 Y 轴方向上移。

我们还将每个产品表示为相同二维空间中的一个点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

上图中用户的位置表明用户喜欢旅行,并且也有一点喜欢摄影。每个产品的位置也是根据它们与摄影和旅行的相关性来放置的。

由于用户和产品只是二维空间中的点,我们可以对它们进行比较和数学运算。例如,从上面的图表中,我们可以找到离用户最近的产品,在这种情况下是行李箱,并自信地说它是用户的一个好推荐。

上面是推荐系统的一个非常基础的介绍(更多内容请参见文章末尾)。这些向量(通常比 2 维大得多)被称为嵌入(用户嵌入表示我们的用户,产品嵌入表示我们网站上的产品)。我们可以使用不同类型的机器学习模型生成它们,虽然它们比我描述的要复杂得多,但基本原理是一样的。

回到我们的问题。对于每个事件,我们需要更新用户的嵌入(在我们的 n 维图表上移动用户),并返回相关的产品作为推荐。

让我们考虑一下生成这些嵌入所需的几个基本步骤,

  1. update-embeddings:更新用户的嵌入

  2. gen-recommendations:获取与用户嵌入相关(或接近)的产品

  3. save:保存生成的推荐和事件

我们可以为每种类型的事件构建一个 Python 服务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

每个微服务会监听一个 Kafka 主题,处理事件,然后将其发送到下一个主题,在那里一个不同的服务会监听。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

由于我们再次使用 Kafka 而不是发送请求,这种架构也给我们带来了之前讨论的所有优势。没有单一的 Python 微服务是单点故障,处理规模也更容易。最后一个服务save-worker需要保存推荐以供将来使用。让我们看看它是如何工作的。

数据接收端

一旦我们处理了一个事件,并生成了推荐,我们需要存储事件和推荐数据。在决定将事件和推荐数据存储在哪里之前,让我们考虑数据存储的要求。

  1. 可扩展性和高写入吞吐量 — 记住我们有大量的事件到达,每个事件还会更新用户推荐。这意味着我们的数据存储应该能够处理非常高数量的写入。我们的数据库应该具有高度的可扩展性,并且能够线性扩展。

  2. 简单查询 — 我们不会执行复杂的 JOIN 操作,也不会进行各种类型的查询。我们的查询需求相对简单,对于给定的用户,返回预计算的推荐列表。

  3. 无 ACID 要求 — 我们的数据库不需要强 ACID 合规性。它不需要对一致性、原子性、隔离性和持久性提供任何保证。

简单来说,我们关注的是一个可以处理极大规模的数据库,没有额外的花里胡哨。

Cassandra 是满足这些要求的完美选择。由于其去中心化的架构,它可以线性扩展,并且能够处理非常高的写入吞吐量,这正是我们需要的。

我们可以使用两个表,一个用于存储每个用户的推荐,另一个用于存储事件。最后的 Python 微服务 save 工作人员将把事件和推荐数据保存在 Cassandra 中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源于作者

查询

查询非常简单。我们已经为每个用户计算并持久化了推荐。要查询这些推荐,我们只需查询我们的数据库并获取特定用户的推荐。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源于作者

完整架构

就这样!我们完成了整个架构,让我们画出完整的架构,看看它是什么样子的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源于作者

进一步学习

Kafka

Kafka 是 LinkedIn 开发的一个惊人的工具,用于处理极大的规模(这篇 LinkedIn 在 2015 年的博客文章讨论了每秒约 1300 万条消息!)。

Kafka 在线性扩展和处理极高规模方面非常出色,但要构建这样的系统,工程师需要了解和理解 Kafka,它是什么,它如何工作,以及与其他工具的对比。

我写了一篇博客文章,解释了 Kafka 是什么,它与消息代理的不同之处,以及 LinkedIn 工程师撰写的原始 Kafka 论文的摘录。如果你喜欢这篇文章,看看我关于 Kafka 的文章 —

[## 系统设计系列:从 10,000 英尺看 Apache Kafka

让我们来看看 Kafka 是什么,它是如何工作的以及我们什么时候应该使用它!

betterprogramming.pub](https://betterprogramming.pub/system-design-series-apache-kafka-from-10-000-feet-9c95af56f18d?source=post_page-----3dd584bd28fa--------------------------------)

Cassandra

Cassandra 是一种独特的数据库,旨在处理非常高的写入吞吐量。它能够处理如此高吞吐量的原因在于其高度可扩展的去中心化架构。我最近写了一篇博客文章讨论 Cassandra、它是如何工作的,以及最重要的何时使用它和何时不使用它 —

## 系统设计解决方案:何时使用 Cassandra 以及何时不使用

关于何时使用 Cassandra 以及何时不使用 Cassandra 的所有信息

medium.com

推荐系统

推荐系统是非常出色的技术,它们几乎在你我今天使用的所有应用程序中都得到了应用。在任何系统中,个性化和推荐系统形成了用户搜索和发现流程的核心。

我一直在写关于搜索系统的内容,并稍微涉及了一下如何在搜索系统中构建基础的个性化功能,但我的下一个话题将深入探讨推荐引擎的细节,它们是如何工作的,以及如何设计它们。如果这对你感兴趣,请在 Medium 上关注我以获取更多内容!我也在 LinkedIn 上发布了很多简短的内容,例如,这篇关于 Kafka Connect 的帖子,描述了它的工作原理以及为什么它如此受欢迎,仅用一个简单的图表。

结论

我喜欢讨论有趣且复杂的话题,并将其分解成 10 分钟的阅读内容。如果你喜欢这篇文章,请在 Medium 上关注我以获取更多类似的内容! 在 LinkedIn 上关注我 ,每天获取更小、更常规的指南,逐步提升你的技术和设计知识。

希望你喜欢这篇文章,如果你对这篇文章有任何反馈或对我接下来应该讨论的内容有任何想法,可以在评论中发表!

从头实现 t-SNE(配合 NumPy)

原文:towardsdatascience.com/t-sne-from-scratch-ft-numpy-172ee2a61df7?source=collection_archive---------2-----------------------#2023-04-14

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

封面图片由作者提供

通过从头实现 t-SNE 并使用 Python,深入理解其内部工作原理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Jacob Pieniazek

·

关注 发表在 Towards Data Science ·17 分钟阅读·2023 年 4 月 14 日

我发现,真正理解任何统计算法或方法的最佳方式之一就是亲自实现它。另一方面,编写这些算法有时会很耗时且非常麻烦,如果别人已经完成了,为什么我还要花时间去做呢——这似乎不太高效,不是吗?这两个观点都很公平,我并不是要为其中一个观点辩护。

本文旨在通过将 原始论文 — 由 Laurens van der Maaten 和 Geoffrey Hinton 合作编写 — 中的数学翻译成 Python 代码实现来帮助读者理解 t-SNE。[1] 我发现这类练习对于揭示统计算法/模型的内部工作机制非常有启发性,并真正测试你对这些算法/模型的理解和假设。你几乎可以肯定地带着比以前更好的理解离开。至少,成功的实现总是非常令人满意的!

本文对任何程度接触 t-SNE 的读者都是可访问的。然而,请注意这篇文章绝对不是

  1. 对 t-SNE 的严格概念性介绍和探索,因为有很多其他很棒的资源已经做到了这一点;尽管如此,我将尽力将数学方程式与其直观/概念性对应物在每个实现阶段连接起来。

  2. 对 t-SNE 的应用及优缺点的全面讨论,以及 t-SNE 与其他降维技术的直接比较。我将会在本文中简要提及这些话题,但绝不会深入探讨。

言归正传,让我们开始对 t-SNE 的简要介绍。

t-SNE 简要介绍

t-分布随机邻居嵌入(*t-SNE)是一个降维工具,主要用于具有大维度特征空间的数据集,能够将数据可视化到更低维度的空间(通常是 2-D)。它特别适用于可视化非线性可分数据,其中线性方法如主成分分析(PCA)会失败。将线性降维框架(如 PCA)推广到非线性方法(如 t-SNE)也称为流形学习。这些方法对于可视化和理解高维非线性数据集的基础结构非常有用,并且对解开和分组在高维空间中相似的观察值很有帮助。有关 t-SNE 和其他流形学习技术的更多信息,scikit-learn 文档 是一个很好的资源。此外,要了解 t-SNE 的一些有趣应用领域,维基百科页面 列出了这些领域及其相关工作的参考资料。

让我们先把名字 t-distributed stochastic neighbor embedding 拆解成它的组成部分。t-SNE 是对 6 年前 Geoffrey Hinton 和 Sam Roweis 在这篇论文中提出的随机邻域嵌入 (SNE) 的扩展。让我们从那里开始。名字中的 stochastic 部分源于目标函数不是凸的,因此不同的初始化可能会产生不同的结果。neighbor embedding 突出了算法的特性——在尽可能保留点的“邻域”结构的同时,将原始高维空间中的点最佳映射到相应的低维空间。SNE 包含以下(简化的)步骤:

  1. 获得原始空间中点之间的相似性矩阵: 计算每个数据点 j 相对于每个数据点 i 的条件概率。这些条件概率是在原始高维空间中使用以 i 为中心的高斯分布计算的,并具有以下解释:i 选择 j 作为其在原始空间中邻居的概率。这会创建一个表示点之间相似性的矩阵。

  2. 初始化: 在低维空间(例如 2-D)中为每个原始空间中的数据点选择随机起点,并在这个新空间中类似地计算新的条件概率。

  3. 映射: 迭代改进低维空间中的点,直到所有条件概率之间的*Kullback-Leibler* 发散度最小化。本质上,我们正在最小化两个空间的相似性矩阵之间的概率差异,以确保在将原始高维数据集映射到低维数据集时,尽可能保留相似性。

t-SNE 主要通过两种方式改进 SNE:

  1. 它最小化了*Kullback-Leibler* 发散度,而不是条件概率之间的发散度。作者称之为“对称 SNE”,因为他们的方法确保了联合概率 p_ij = p_ji这使得成本函数的表现大大改善,更易于优化。

  2. 它使用具有一个自由度的Student-t 分布(也就是柯西分布)来计算点之间的相似性,而不是在低维空间中使用高斯分布(上面的第 2 步)。在这里我们可以看到 t-SNE 中的“t”来自哪里。这一改进有助于缓解作者所强调的“拥挤问题”,并进一步改善优化问题。 “拥挤问题”可以这样理解:假设我们有一个 10 维空间,那么在 2 维空间中可用的空间将不足以准确捕捉那些适度不相似的点,而与 10 维空间中相邻点所占用的空间相比,2 维空间的空间远远不够。更简单地说,只需设想将 3 维空间投影到 2 维空间,3 维空间将有更多的整体空间来建模相似性,相对于投影到 2 维的空间。Student-t 分布通过具有比正态分布更重的尾部来帮助缓解这个问题。有关这个问题的更深入的讨论,请参见原始论文

如果这些内容没有立即跟上,那也没关系!我希望当我们在代码中实现这些时,所有部分都会迎刃而解。主要的要点是:t-SNE 在高维空间中通过“数据点选择其他点作为邻居”的联合概率来建模数据点之间的相似性,然后尝试找到这些点映射到低维空间的最佳方式,同时尽可能保留原始高维相似性。

从头开始的实现

现在让我们继续了解 t-SNE,方法是实现 Laurens van der Maaten 和 Geoffrey Hinton 在论文中提出的算法原版。我们将首先逐步实现下面的算法 1,这将涵盖主算法的 95%。作者还提到了两个额外的改进:1) 早期夸张和 2) 自适应学习率。我们将仅讨论添加早期夸张,因为这有助于解释实际算法的内部工作原理,而自适应学习率则侧重于提高收敛速度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

算法 1(见论文

1. 输入和输出

根据原始论文,我们将使用来自 OpenML 的公开 MNIST 数据集,该数据集包含从 0 到 9 的手写数字图像。[2] 我们还将从数据集中随机抽取 1000 张图像,并使用主成分分析 (PCA) 降维,将组件数保留为 30。这两者都是为了提高算法的计算时间,因为这里的代码没有针对速度进行优化,而是为了可解释性和学习。

from sklearn.datasets import fetch_openml
from sklearn.decomposition import PCA
import pandas as pd

# Fetch MNIST data
mnist = fetch_openml('mnist_784', version=1, as_frame=False)
mnist.target = mnist.target.astype(np.uint8)

X_total = pd.DataFrame(mnist["data"])
y_total = pd.DataFrame(mnist["target"])

X_reduced = X_total.sample(n=1000)
y_reduced = y_total.loc[X_total.index]

# PCA to keep 30 components
X = PCA(n_components=30).fit_transform(X_reduced) 

这将是我们的 X 数据集,每一是一个图像,每一是一个特征,或者在这种情况下是主成分(即原始像素的线性组合):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从 MNIST 数据集中抽取的 1000 个样本及前 30 个主成分

我们还需要指定代价函数参数——困惑度——以及优化参数——迭代次数、学习率和动量。我们现在暂时不讨论这些参数,而是在每个阶段出现时再进行处理。

就输出而言,请记住,我们寻求的是原始数据集 X 的低维映射。在整个示例中,我们将把原始空间映射到二维空间。因此,我们的新输出将是现在以二维空间表示的 1000 张图像,而不是原始的 30 维空间:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所需的二维空间输出

2. 计算原始空间中 X 的亲和力/相似度

现在我们有了输入,第一步是计算原始高维空间中的成对相似度。即,对于每个图像 i,我们计算 i 在原始空间中选择图像 j 作为其邻居的概率。这些概率是通过围绕每个点的正态分布计算的,然后归一化为总和为 1。数学上,我们有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Eq. (1) — 高维亲和力

请注意,在我们的例子中,n = 1000,这些计算将产生一个 1000 x 1000 的相似度评分矩阵。注意,我们在 i = j 时将 p = 0,因为我们正在建模成对相似度。然而,你可能会注意到,我们没有提到如何确定 σ。这个值是通过基于用户指定的期望困惑度的网格搜索为每个观察值 i 确定的。我们将立即讨论这个问题,但首先让我们看看如何编写上述公式(1)的代码:

def get_original_pairwise_affinities(X: np.ndarray, perplexity: int = 10) -> np.ndarray:
    """
    Function to obtain affinities matrix.

    Parameters:
    X (np.ndarray): The input data array.
    perplexity (int): The perplexity value for the grid search.

    Returns:
    np.ndarray: The pairwise affinities matrix.
    """

    n = len(X)

    print("Computing Pairwise Affinities....")

    p_ij = np.zeros(shape=(n, n))
    for i in range(0, n):
        # Equation 1 numerator
        diff = X[i] - X
        σ_i = grid_search(diff, i, perplexity)  # Grid Search for σ_i
        norm = np.linalg.norm(diff, axis=1)
        p_ij[i, :] = np.exp(-(norm**2) / (2 * σ_i**2))

        # Set p = 0 when j = i
        np.fill_diagonal(p_ij, 0)

        # Equation 1
        p_ij[i, :] = p_ij[i, :] / np.sum(p_ij[i, :])

    # Set 0 values to minimum numpy value (ε approx. = 0)
    ε = np.nextafter(0, 1)
    p_ij = np.maximum(p_ij, ε)

    print("Completed Pairwise Affinities Matrix. \n")

    return p_ij

在我们查看这段代码的结果之前,让我们讨论一下如何通过 grid_search() 函数确定 σ 的值。给定一个指定的 perplexity 值(在这种情况下可以大致理解为每个点的最近邻数量),我们对一系列 σ 值进行网格搜索,以便使以下方程对于每个 i 尽可能接近等式:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Perplexity

其中 H§ 是 P 的香农

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

P 的香农熵

在我们的案例中,我们将 perplexity 设置为 10,并将搜索空间定义为 [0.01 * 图像 ij 之间差异的范数的标准差,5 * 图像 ij 之间差异的范数的标准差],分成 200 个相等的步长。知道这一点后,我们可以按如下方式定义我们的 grid_search() 函数:

def grid_search(diff_i: np.ndarray, i: int, perplexity: int) -> float:
    """
    Helper function to obtain σ's based on user-specified perplexity.

    Parameters:
        diff_i (np.ndarray): Array containing the pairwise differences between data points.
        i (int): Index of the current data point.
        perplexity (int): User-specified perplexity value.

    Returns:
        float: The value of σ that satisfies the perplexity condition.
    """

    result = np.inf  # Set first result to be infinity

    norm = np.linalg.norm(diff_i, axis=1)
    std_norm = np.std(norm)  # Use standard deviation of norms to define search space

    for σ_search in np.linspace(0.01 * std_norm, 5 * std_norm, 200):
        # Equation 1 Numerator
        p = np.exp(-(norm**2) / (2 * σ_search**2))

        # Set p = 0 when i = j
        p[i] = 0

        # Equation 1 (ε -> 0)
        ε = np.nextafter(0, 1)
        p_new = np.maximum(p / np.sum(p), ε)

        # Shannon Entropy
        H = -np.sum(p_new * np.log2(p_new))

        # Get log(perplexity equation) as close to equality
        if np.abs(np.log(perplexity) - H * np.log(2)) < np.abs(result):
            result = np.log(perplexity) - H * np.log(2)
            σ = σ_search

    return σ

有了这些函数,我们可以通过p_ij = get_original_pairwise_affinities(X)计算亲和矩阵,从而得到以下矩阵:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

原始高维空间中条件概率的亲和矩阵

请注意,主对角线元素按构造设置为 ε ≈ 0(每当 i = j 时)。请记住,t-SNE 算法的一个关键扩展是计算联合概率而不是条件概率。这可以简单地按如下方式计算:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将条件概率转换为联合概率

因此,我们可以定义一个新函数:

def get_symmetric_p_ij(p_ij: np.ndarray) -> np.ndarray:
    """
    Function to obtain symmetric affinities matrix utilized in t-SNE.

    Parameters:
    p_ij (np.ndarray): The input affinity matrix.

    Returns:
    np.ndarray: The symmetric affinities matrix.

    """
    print("Computing Symmetric p_ij matrix....")

    n = len(p_ij)
    p_ij_symmetric = np.zeros(shape=(n, n))
    for i in range(0, n):
        for j in range(0, n):
            p_ij_symmetric[i, j] = (p_ij[i, j] + p_ij[j, i]) / (2 * n)

    # Set 0 values to minimum numpy value (ε approx. = 0)
    ε = np.nextafter(0, 1)
    p_ij_symmetric = np.maximum(p_ij_symmetric, ε)

    print("Completed Symmetric p_ij Matrix. \n")

    return p_ij_symmetric

将上面的p_ij代入,我们得到p_ij_symmetric = get_symmetric_p_ij(p_ij),从而获得以下symmetric亲和矩阵:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

原始高维空间中联合概率的对称亲和矩阵

现在我们已经完成了 t-SNE 中的第一个主要步骤!我们计算了原始高维空间中的对称亲和矩阵。在我们深入优化阶段之前,我们将在接下来的两个步骤中讨论优化问题的主要组件,然后将它们结合到我们的 for 循环中。

3. 样本初始解决方案及计算低维亲和矩阵

现在我们想在低维空间中随机抽样一个初始解决方案,如下所示:

def initialization(
    X: np.ndarray, n_dimensions: int = 2, initialization: str = "random"
) -> np.ndarray:
    """
    Obtain initial solution for t-SNE either randomly or using PCA.

    Parameters:
        X (np.ndarray): The input data array.
        n_dimensions (int): The number of dimensions for the output solution. Default is 2.
        initialization (str): The initialization method. Can be 'random' or 'PCA'. Default is 'random'.

    Returns:
        np.ndarray: The initial solution for t-SNE.

    Raises:
        ValueError: If the initialization method is neither 'random' nor 'PCA'.
    """

    # Sample Initial Solution
    if initialization == "random" or initialization != "PCA":
        y0 = np.random.normal(loc=0, scale=1e-4, size=(len(X), n_dimensions))
    elif initialization == "PCA":
        X_centered = X - X.mean(axis=0)
        _, _, Vt = np.linalg.svd(X_centered)
        y0 = X_centered @ Vt.T[:, :n_dimensions]
    else:
        raise ValueError("Initialization must be 'random' or 'PCA'")

    return y0

其中调用 y0 = initialization(X) 我们得到一个随机的起始解决方案:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2-D 初始随机解决方案

现在,我们想在这个低维空间中计算亲和矩阵。然而,请记住,我们是利用具有 1 个自由度的学生-t 分布来完成的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 (4) — 低维亲和

同样地,我们设置 q = 0i = j。注意这个方程与公式 (1) 的不同之处在于分母涉及所有 i,因此按照构造是对称的。将其转化为代码,我们得到:

def get_low_dimensional_affinities(Y: np.ndarray) -> np.ndarray:
    """
    Obtain low-dimensional affinities.

    Parameters:
    Y (np.ndarray): The low-dimensional representation of the data points.

    Returns:
    np.ndarray: The low-dimensional affinities matrix.
    """

    n = len(Y)
    q_ij = np.zeros(shape=(n, n))

    for i in range(0, n):
        # Equation 4 Numerator
        diff = Y[i] - Y
        norm = np.linalg.norm(diff, axis=1)
        q_ij[i, :] = (1 + norm**2) ** (-1)

    # Set p = 0 when j = i
    np.fill_diagonal(q_ij, 0)

    # Equation 4
    q_ij = q_ij / q_ij.sum()

    # Set 0 values to minimum numpy value (ε approx. = 0)
    ε = np.nextafter(0, 1)
    q_ij = np.maximum(q_ij, ε)

    return q_ij

这里我们正在寻找一个 1000 x 1000 的亲和矩阵,但现在是在低维空间中。调用 q_ij = get_low_dimensional_affinities(y0) 我们得到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

新低维空间中联合概率的对称亲和矩阵

4. 计算成本函数的梯度

回顾一下,我们的成本函数是高维空间和低维空间中联合概率分布的 Kullback-Leibler 散度:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

联合概率分布的 Kullback-Leibler 散度

直观上,我们希望最小化亲和矩阵 p_ijq_ij 之间的差异,从而最好地保留原始空间的“邻域”结构。使用梯度下降法来解决优化问题,但首先让我们看看如何计算上面成本函数的梯度。作者推导了成本函数的梯度(见 论文 的附录 A)如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

成本函数的梯度(公式 5,但来自附录)

在 Python 中,我们有:

def get_gradient(p_ij: np.ndarray, q_ij: np.ndarray, Y: np.ndarray) -> np.ndarray:
    """
    Obtain gradient of cost function at current point Y.

    Parameters:
    p_ij (np.ndarray): The joint probability distribution matrix.
    q_ij (np.ndarray): The Student's t-distribution matrix.
    Y (np.ndarray): The current point in the low-dimensional space.

    Returns:
    np.ndarray: The gradient of the cost function at the current point Y.
    """

    n = len(p_ij)

    # Compute gradient
    gradient = np.zeros(shape=(n, Y.shape[1]))
    for i in range(0, n):
        # Equation 5
        diff = Y[i] - Y
        A = np.array([(p_ij[i, :] - q_ij[i, :])])
        B = np.array([(1 + np.linalg.norm(diff, axis=1)) ** (-1)])
        C = diff
        gradient[i] = 4 * np.sum((A * B).T * C, axis=0)

    return gradient

输入相关参数,我们通过 gradient = get_gradient(p_ij_symmetric,q_ij,y0) 得到在 y0 处的梯度及相应输出:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始解(y0)下成本函数的梯度

现在,我们已经准备好解决优化问题的所有部分!

5. 迭代与优化低维映射

为了更新我们的低维映射,我们使用 带动量的梯度下降,正如作者所述:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更新规则(带动量的梯度下降)

其中 η 是我们的 学习率α(t) 是我们随时间变化的动量项。学习率控制每次迭代的步长,而动量项使优化算法在搜索空间的平滑方向上获得惯性,同时不被梯度的噪声部分所困扰。我们将例子中的 η=200,并且如果 t < 250 时将 α(t)=0.5,否则将 α(t)=0.8。以上是计算更新规则所需的所有组件,因此我们可以在设定的迭代次数 T 上进行优化(我们将 T=1000)。

在设置迭代方案之前,首先介绍作者所称的“早期夸张”增强。这一术语是一个常数,用于缩放原始的亲和度矩阵 p_ij。这将更多地强调在新空间中早期建模非常相似的点(原始空间中 p_ij 的高值),从而形成高度相似点的“簇”。早期夸张在迭代方案的开始阶段 (T<250) 中开启,然后关闭。在我们的情况下,早期夸张将设置为 4。我们将在下面的可视化中看到它的实际效果。

现在,将所有算法部分结合起来,我们得到了如下内容:

def tsne(
    X: np.ndarray,
    perplexity: int = 10,
    T: int = 1000,
    η: int = 200,
    early_exaggeration: int = 4,
    n_dimensions: int = 2,
) -> list[np.ndarray, np.ndarray]:
    """
    t-SNE (t-Distributed Stochastic Neighbor Embedding) algorithm implementation.

    Args:
        X (np.ndarray): The input data matrix of shape (n_samples, n_features).
        perplexity (int, optional): The perplexity parameter. Default is 10.
        T (int, optional): The number of iterations for optimization. Default is 1000.
        η (int, optional): The learning rate for updating the low-dimensional embeddings. Default is 200.
        early_exaggeration (int, optional): The factor by which the pairwise affinities are exaggerated
            during the early iterations of optimization. Default is 4.
        n_dimensions (int, optional): The number of dimensions of the low-dimensional embeddings. Default is 2.

    Returns:
        list[np.ndarray, np.ndarray]: A list containing the final low-dimensional embeddings and the history
            of embeddings at each iteration.

    """
    n = len(X)

    # Get original affinities matrix
    p_ij = get_original_pairwise_affinities(X, perplexity)
    p_ij_symmetric = get_symmetric_p_ij(p_ij)

    # Initialization
    Y = np.zeros(shape=(T, n, n_dimensions))
    Y_minus1 = np.zeros(shape=(n, n_dimensions))
    Y[0] = Y_minus1
    Y1 = initialization(X, n_dimensions)
    Y[1] = np.array(Y1)

    print("Optimizing Low Dimensional Embedding....")
    # Optimization
    for t in range(1, T - 1):
        # Momentum & Early Exaggeration
        if t < 250:
            α = 0.5
            early_exaggeration = early_exaggeration
        else:
            α = 0.8
            early_exaggeration = 1

        # Get Low Dimensional Affinities
        q_ij = get_low_dimensional_affinities(Y[t])

        # Get Gradient of Cost Function
        gradient = get_gradient(early_exaggeration * p_ij_symmetric, q_ij, Y[t])

        # Update Rule
        Y[t + 1] = Y[t] - η * gradient + α * (Y[t] - Y[t - 1])  # Use negative gradient

        # Compute current value of cost function
        if t % 50 == 0 or t == 1:
            cost = np.sum(p_ij_symmetric * np.log(p_ij_symmetric / q_ij))
            print(f"Iteration {t}: Value of Cost Function is {cost}")

    print(
        f"Completed Low Dimensional Embedding: Final Value of Cost Function is {np.sum(p_ij_symmetric * np.log(p_ij_symmetric / q_ij))}"
    )
    solution = Y[-1]

    return solution, Y

调用 solution, Y = tSNE(X) 我们得到以下输出:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 solution 是最终的 2-D 映射,Y 是我们在每次迭代步骤中的 2-D 映射值。绘制 Y 的演变,其中 Y[-1] 是我们的最终 2-D 映射,我们得到(注意算法在早期夸张开启和关闭时的表现):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

t-SNE 算法中的 2-D 映射演变

我建议尝试不同的参数值(如困惑度、学习率、早期夸张等),看看解决方案如何变化(参见原始论文scikit-learn 文档获取使用这些参数的指南)。

结论

就这样,我们从零开始实现了 t-SNE!我希望你发现这个练习对 t-SNE 的内部工作有启发,至少是令人满意的。请注意,这个实现并不旨在优化速度,而是为了理解。t-SNE 算法的改进包括提高计算速度和性能,例如Barnes-Hut 算法的变体(基于树的方法)、使用 PCA 作为嵌入的初始化,或使用如自适应学习率等额外的梯度下降扩展。scikit-learn中的实现采用了许多这些增强功能。

一如既往,我希望你阅读这篇文章的乐趣与我写作时的乐趣一样。

资源

[1] van der Maaten, L.J.P.; Hinton, G.E. 使用 t-SNE 可视化高维数据。《机器学习研究期刊》9:2579–2605, 2008。

[2] LeCun et al. (1999):手写数字 (图像) 的 MNIST 数据集 许可证:CC BY-SA 3.0

通过这个 GitHub 仓库访问所有代码: github.com/jakepenzak/Blog-Posts

感谢你阅读我的帖子!我在 Medium 上的帖子旨在探讨利用 计量经济学 统计学/机器学习 技术的实际和理论应用。此外,我还希望通过理论和模拟提供有关各种方法论的理论基础的帖子。最重要的是,我写作是为了学习并帮助他人学习!我希望使复杂的主题对大家稍微更加易懂。如果你喜欢这篇帖子,请考虑 在 Medium 上关注我

T5:文本到文本的变换器(第一部分)

原文:towardsdatascience.com/t5-text-to-text-transformers-part-one-6b655f27c79a

创建一个统一的语言建模框架

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Cameron R. Wolfe, Ph.D.

·发表于Towards Data Science ·14 分钟阅读·2023 年 6 月 27 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(照片由Patrick Tomasso拍摄,来源于Unsplash

迁移学习范式包括两个主要阶段。首先,我们在一大堆数据上对深度神经网络进行预训练。然后,我们在一个更具体的下游数据集上对这个模型进行微调(即,再训练它一段时间)。这些阶段的具体实现可能有多种形式。例如,在计算机视觉中,我们通常使用有监督学习目标在 ImageNet 数据集上对模型进行预训练。然后,这些模型在下游数据集上进行有监督微调(即,我们实际尝试解决的任务)。而在自然语言处理(NLP)中,我们通常在未标记的文本语料库上进行自监督预训练。

结合大型深度神经网络和庞大的(预)训练数据集通常会产生令人印象深刻的结果。这一发现对自然语言处理(NLP)尤其适用。由于原始文本数据在互联网上可以自由获得,我们可以简单地下载大量文本语料库,先在这些数据上预训练一个大型神经网络,然后在各种下游任务上微调模型(或仅使用零/少样本学习技术)。这一大规模迁移学习方法最初由 BERT 探索,该方法在未标记的数据上使用掩蔽目标预训练了一个变换器编码器,然后在下游语言任务上进行微调。

BERT [2] 的成功不可小觑(即,在几乎所有语言基准上都取得了新的最先进性能)。因此,自然语言处理(NLP)社区开始深入研究迁移学习这一主题,提出了许多新的扩展和改进。由于这一领域的发展迅速,各种方法的比较变得困难。文本到文本转换器(T5)模型 [1] 提出了一个统一的框架,用于研究 NLP 中的迁移学习方法,使我们能够分析不同的设置并得出一套最佳实践。这套最佳实践包括 T5,这是一种用于语言理解任务的最先进模型和训练框架。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

相关历史和背景

T5 将现有的迁移学习技术重新定义为统一的格式,进行比较,并确定最佳实践以获得高性能结果。但这意味着什么?迁移学习是什么,为什么我们应该关注它? 为了回答这些问题,我们将首先概述一些重要的概念,包括迁移学习和不同的 Transformer 架构变体,这些对于理解 [1] 中的分析至关重要。从这里开始,我们将通过解释 BERT [2] 架构来提供一些历史背景,这一架构使得迁移学习在自然语言处理(NLP)任务中变得流行。

什么是迁移学习?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练神经网络的不同选项(由作者创建)

如果我们想训练一个神经网络来解决某个任务,我们有两个基本的选择。

  1. 从头开始训练:随机初始化你的神经网络,并在你的目标任务上进行训练(以监督方式)。

  2. 迁移学习:在一个独立的数据集上进行预训练,然后在目标任务上进行微调(即,进一步训练)。

通常,预训练是在比下游目标数据集大得多的数据集上进行的。一般而言,预训练会大幅提高数据效率。模型在微调期间学习得更快,甚至可能表现更好。迁移学习过程可以有许多不同的形式。例如,在计算机视觉中,我们可能会在 ImageNet 上进行模型预训练(使用监督学习),然后在像 CIFAR-10/100 这样的较小数据集上进行微调。对于自然语言处理(NLP)任务,情况稍有不同。通常,我们使用自监督预训练目标(例如,掩蔽语言建模因果语言建模)与未标记的文本。

不同的 Transformer 架构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [6])

Transformer,如在 [1] 中最初提出的,使用编码器-解码器架构,如上所示。有关此架构的更深入概述,请查看链接 here。然而,编码器-解码器 Transformer 架构并不是我们唯一的选择!BERT 使用 仅编码器架构,而大多数 现代大型语言模型(LLMs)基于 仅解码器的 Transformers。让我们花一点时间了解这些架构变体之间的区别。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Transformer 编码器中的双向自注意力(由作者创建)

自注意力的简介。 自注意力操作将一个令牌向量序列作为输入,并生成一个长度相同的新的变换后令牌向量序列作为输出;如上所示。这个新序列的每个条目都是输入序列中向量的加权平均值。具体而言,我们计算输出序列中每个令牌向量的方法如下,其中 y_ix_j 分别是输出和输入序列的元素。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(由作者创建)

上述权重 w_{i, j} 是一个注意力分数,它是 x_ix_j 的函数。简单来说,这个分数捕捉了当前令牌在计算其新表示时应该“关注”序列中的其他令牌的程度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [6])

单堆栈还是双堆栈? 原始 Transformer 架构使用两个“堆栈” 的 Transformer 层;见上文。第一个堆栈(编码器模块)由几个包含双向自注意力和 前馈神经网络 的块组成。第二个堆栈(解码器模块)非常相似,但它使用 掩码自注意力,并增加了一个“交叉注意力”机制,该机制在执行自注意力时考虑对应编码器层中的激活。Transformer 最初用于 序列到序列 任务(例如语言翻译)。对于其他任务,单堆栈 Transformer 模型变得非常流行:

  • 语言模型使用仅解码器架构

  • BERT 风格的模型使用仅编码器架构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

注意力掩码。 变压器架构的变体有一个主要区别:在其注意力层中使用的掩码类型。在这里,当我们说“掩码”时,我们指的是在自注意力计算过程中某些标记被掩盖(或忽略)。简单来说,某些标记可能仅查看完整输入序列中的一部分其他标记。上图描绘了自注意力的不同掩码选项。

仅编码器模型利用双向(或完全可见)自注意力,这在自注意力过程中考虑了整个序列中的所有标记。自注意力中的每个标记表示是通过序列中所有其他标记的加权平均来计算的。相比之下,仅解码器模型使用因果自注意力,其中每个标记仅考虑序列中其之前的标记。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

我们还可以通过定义“前缀”来采用混合方法。更具体地说,我们可以对序列开头的一组标记(即前缀)执行双向自注意力,然后对序列中其余的标记执行因果自注意力;见上文。完全可见(或双向)自注意力对于处理前缀或执行分类任务非常有用。然而,某些应用(例如,语言建模)在训练过程中需要因果自注意力,以防止变压器“看到未来”(即在生成输出时仅复制正确的标记)。

T5 使用什么? 尽管[1]中的分析考虑了许多变压器架构,但 T5 主要使用的是标准的编码器-解码器架构。除了少数小修改外,该模型与最初提出的变压器[6]非常相似。由于编码器仅架构设计用于标记或序列级分类,而不是像翻译或总结这样的生成任务,[1]中没有探索它们。T5 旨在找到一种统一的方法(基于迁移学习)来解决许多语言理解任务。

BERT:NLP 的迁移学习

在早期,NLP 中的迁移学习通常使用经过 因果语言建模目标 预训练的递归神经网络。然而,随着 BERT [2] 的提出,一切发生了变化。BERT 是一种基于变换器的模型 [6],其使用 自监督目标 进行预训练。BERT 可以在大量未标记的文本上进行预训练,然后微调以对句子(甚至句子中的单个标记)进行高精度分类。在提出时,BERT 在几乎所有被考虑的 NLP 任务上都设立了新的最先进水平,巩固了迁移学习在 NLP 中的主导地位。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 BERT 执行自监督 MLM 预训练(由作者创建)

为了使这一点更加具体,BERT 在预训练过程中依赖于一种“去噪”目标,称为 掩码语言建模 (MLM);见上文。虽然这听起来可能有些复杂,但其核心思想很简单,我们只需:

  1. 将输入序列中的一些标记掩盖,用特殊的 [MASK] 标记替代

  2. 使用 BERT 处理这些被破坏/修改过的序列

  3. 训练 BERT 以准确预测掩码标记

精确的实现要复杂一些。我们随机选择 15% 的标记,然后将它们替换为 [MASK] 标记(90% 的概率)或随机标记(10% 的概率)。通过在足够大的预训练语料库上使用这一目标,BERT 可以学习大量的一般语言学知识,使其成为一个高效的迁移学习模型。

T5 与 BERT 有什么关系? BERT 的提出展示了迁移学习是一种解决 NLP 问题的有效方法。许多人很快开始使用 BERT,尝试新技术并提出改进建议。因此,该领域充斥着各种使用类似 BERT 模型进行迁移学习的选项。T5 [1] 在这一研究方向上继续前进,但试图使用统一的框架来分析所有这些不同的提案,从而为我们提供了关于 NLP 中迁移学习最佳实践的更清晰的视角。最终的 T5 模型利用这些最佳实践进行训练,以达到最先进的性能。

T5 与 LLMs 的关系是什么? 目前,我们正在看到生成 AI 领域的重大革命,其中 LLMs(基于仅解码器的变压器架构)被用于通过语言模型预训练解决语言任务,然后进行 零/少样本学习。LLMs 很出色,但 T5 存在于一个相对独特的工具和研究领域。即,T5 主要关注那些明确通过编码器处理输入,然后通过单独的解码器生成输出的模型。此外,T5 采用迁移学习方法(即,预训练后在每个目标任务上进行微调),而不是零/少样本学习。

其他有用的链接

  • 变压器架构 [link]

  • 自注意力 [link]

  • BERT 模型 [link]

  • 语言模型的基础 [link]

T5:统一的文本到文本变压器

T5 的贡献并不是一种新颖的架构或训练方法。相反,[1]中进行的研究完全基于现有技术。T5 考虑了 NLP 领域中迁移学习管道的各个方面,例如不同的(未标记的)数据集、预训练目标、基准测试和微调方法。然而,所有这些方面都是通过统一的文本到文本格式进行研究的。T5 的目标是 i) 分析迁移学习设置和 ii) 确定最有效的方法。

文本到文本框架

T5 将所有文本处理问题转换为“文本到文本”格式(即,将文本作为输入并生成文本作为输出)。这种通用结构也被采用于具有零/少样本学习的 LLMs,使我们能够用统一的方法建模和解决各种不同的任务。我们可以将相同的模型、目标、训练程序和解码过程应用于我们考虑的每个任务!我们只需采用 提示 方法,并要求我们的语言模型以文本格式生成答案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

为了让这一点更加具体,T5 解决的所有任务都可以转换为文本到文本格式,如下所示:

  1. 为原始输入序列添加任务特定的前缀

  2. 将这个序列输入到变压器中

  3. 将模型的目标形式化为文本序列

使用这种格式,我们可以轻松执行诸如总结或翻译(即目标自然是一个序列)之类的任务。此外,我们可以通过仅训练模型生成与正确类别相关的文本来进行分类。这一过程在回归问题(即我们必须将实值输出舍入到最近的小数并将其视为分类问题)时会变得有些复杂,但对于大多数语言任务,它往往效果很好。示例见上图。

“如果我们的模型在文本分类任务中输出的文本与任何可能的标签都不对应,那么会出现问题……在这种情况下,我们总是将模型的输出视为错误,尽管我们在任何训练模型中都没有观察到这种行为。” — 来自[1]

T5 会针对它解决的每个任务进行微调。这与使用少样本学习的 LLM 和使用多任务学习一次性解决多个任务的 NLP 十项全能[3]形成对比。

T5 是如何研究的?

所有在[1]中进行的分析都使用了上述统一的文本到文本框架,因为它允许将各种不同的语言理解任务转换为共享格式。此外,T5 的分析使用了相同的基础变换器架构和预训练数据集。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自[6])

模型。 如前所述,变换器架构,正如[6]中最初提出的那样,包含编码器和解码器模块。最近对语言建模的研究探讨了只使用编码器或解码器的架构变体;例如,BERT只使用编码器[2],而大多数(大型)语言模型只使用解码器。T5 使用了一个与原始变换器非常相似的编码器-解码器架构。不同之处在于:

  1. LayerNorm在每次注意力和前馈变换之前立即应用(即,位于残差路径之外)

  2. 对于 LayerNorm 未使用加性偏置(即,见这里;我们只使用缩放并消除加性偏置)

  3. 使用了一个简单的位置嵌入方案,将一个标量添加到计算注意力权重时使用的相应logit中。

  4. 在整个网络中应用了 Dropout(例如,注意力权重、前馈网络、跳跃连接等)

这些修改在上图中有所说明。使用该模型(以及其他一些模型),T5 可以测试许多不同的迁移学习设置,以得出一套最佳实践。

预训练数据集。 T5 在 Colossal Clean Crawled Corpus(C4)上进行预训练,这是一个 750GB 的“相对干净”的英文文本数据集,详见[1]。尽管先前的工作中提出了各种预训练数据集,[1]中的作者选择构建自己的数据集,因为先前的数据集不可公开获取,使用的过滤规则有限,范围有限(例如,仅来自Creative Commons),或仅专注于机器翻译的平行数据(即多个不同语言中的相同句子版本)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自[4])

值得注意的是,C4 后来被用作 MassiveText 数据集的一个子集,该数据集用于预训练GopherChinchilla[4, 5]。请参见上表,以了解该数据集的规模指标,这有助于更好地理解 C4 与用于训练现代 LLM 的预训练数据集的相对大小。对于 LLM,我们已经看到,预训练仅解码器模型在足够大的数据集上是其成功的关键。不同架构的变换器,如 T5,亦是如此。在大型未标记数据集上的广泛预训练有利于更好的下游表现。

实验设置。 T5 在 C4 上进行预训练,然后微调以解决各种下游任务。然而,在这个框架中使用的确切设置是可变的。即,我们可以更改:

  • 变换器架构

  • 预训练设置(即任务或数据量)

  • 微调设置

  • 模型的规模/大小

通过逐一更改这些设置并评估结果,我们可以为 NLP 中的迁移学习开发一套最佳实践,从而将 BERT 之后的众多提议提炼成一个有效的管道,用于创建有效的语言理解模型。

要点

本文涵盖了与 T5 模型相关的所有初步信息,包括重要的背景信息和使用的基本实验框架。在下一篇文章中,我们将详细介绍[1]中进行的广泛分析,揭示 NLP 中迁移学习的最佳实践。目前,T5 的主要要点概述如下。

迁移学习是强大的。 迁移学习是指在某些独立数据集上预训练深度学习模型,然后在下游目标数据集(即我们实际要解决的任务)上微调(或进一步训练)该模型。如果在足够大且对齐(即,与下游任务类似)的数据集上进行,预训练是非常有效的。模型在微调期间可以学习得更快,甚至达到更高的准确率。这种技术在不同领域(例如计算机视觉和自然语言处理)中都有效,但用于预训练或微调的确切方法可能会有所不同。

“虽然我们在本文中没有明确测量数据效率的提升,但我们强调这是迁移学习范式的主要好处之一。” — 来源于 [1]

BERT 之后是什么? BERT [2] 的提出是一个巨大的突破,普及了迁移学习在自然语言处理任务中的应用。事实上,BERT 在几乎所有涉及的任务上都设置了新的最先进性能。由于其成功,研究社区采纳并迭代了 BERT 的方法。T5 尝试统一 BERT 提出后的所有后续工作和分析,提供了对最有效迁移学习方法的更清晰视角。

通用任务制定。 为了创建一个统一的框架,以便研究多种不同的迁移学习方法,T5 提出了一个通用的文本到文本框架。类似于用于大型语言模型(LLM)的提示和少样本学习技术,这个文本到文本框架可以将任何语言任务重组为文本输入和输出。具体来说,这通过在文本输入中附加特定任务的前缀(即,让 T5 知道它正在解决什么任务)来完成,并使用 T5 的解码器模块生成与期望目标(例如标签、回归值或文本序列)对应的文本。

结束语

感谢阅读本文。我是 Cameron R. WolfeRebuy 的 AI 总监。我研究深度学习的实证和理论基础。你也可以查看我在 Medium 上的 其他文章!如果你喜欢,请在 twitter 上关注我,或订阅我的 Deep (Learning) Focus 电子通讯,我在其中通过易于理解的热门论文概述帮助读者深入了解 AI 研究中的主题。

参考文献

[1] Raffel, Colin, et al. “Exploring the limits of transfer learning with a unified text-to-text transformer.” The Journal of Machine Learning Research 21.1 (2020): 5485–5551.

[2] Devlin, Jacob, et al. “Bert: Pre-training of deep bidirectional transformers for language understanding.” arXiv preprint arXiv:1810.04805 (2018).

[3] McCann, Bryan, 等人。“自然语言十项全能:将多任务学习应用于问答。” arXiv 预印本 arXiv:1806.08730 (2018)。

[4] Rae, Jack W., 等人。“语言模型的扩展:训练 Gopher 的方法、分析与见解。” arXiv 预印本 arXiv:2112.11446 (2021)。

[5] Hoffmann, Jordan, 等人。“训练计算最优的大型语言模型。” arXiv 预印本 arXiv:2203.15556 (2022)。

[6] Vaswani, Ashish, 等人。“注意力机制才是你所需要的。” 神经信息处理系统进展 30 (2017)。

T5: 文本到文本的变换器(第二部分)

原文:towardsdatascience.com/t5-text-to-text-transformers-part-two-837ba23a9eb4

大型语言模型的最佳迁移学习

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Cameron R. Wolfe, Ph.D.

·发表于Towards Data Science ·阅读时间 14 分钟·2023 年 7 月 5 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(照片来源于Patrick TomassoUnsplash

BERT [5] 的提出促使了自然语言处理(NLP)领域中迁移学习方法的普及。由于互联网上大量未标记文本的广泛存在,我们可以轻松地*(i)* 在大量原始文本上预训练大型变换器模型,以及*(ii)* 微调这些模型以准确解决下游任务。这种方法非常有效,但其新兴的受欢迎程度导致许多替代方法和改进被提出。随着这些新方法的出现,人们不禁开始想:NLP 中迁移学习的最佳实践是什么?

这个问题通过对统一的文本到文本变换器(T5)模型的分析得到了回答。T5 在预训练和微调期间都将所有任务重新格式化为文本到文本的格式,这意味着模型接收文本输入并生成文本输出。利用这种统一格式,T5 可以分析各种不同的迁移学习设置,从而允许比较多种方法。在之前的通讯中,我们了解了 T5 模型的格式、架构和整体方法。

在本期通讯中,我们将概述 T5 进行的分析,包括不同预训练目标、架构、模型/数据规模和 NLP 领域迁移学习的训练方法的实证比较。在[1]中,这些选项被逐一研究,以确定它们对 T5 性能的影响。通过研究这些分析,我们得出了一套最佳实践,这些实践(当结合在一起时)产生了最先进的 T5 框架,能够以极高的准确性解决语言理解任务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

基础知识

我们已经覆盖了 T5 架构的动机和基础知识。请查看链接中的帖子 这里。我们也可以快速回顾这些思想。 BERT [5] 的提案普及了 迁移学习 范式(即,在某些独立数据集上预训练模型,然后在目标数据集上进行微调)用于 NLP。然而,BERT 的有效性使许多研究人员将重点放在这个话题上,并提出各种修改和改进。T5 的想法是 (i) 将所有语言任务转换为统一的文本到文本格式(见下图),并 (ii) 研究各种不同的 NLP 迁移学习设置,以推断出最有效的技术。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

语言建模 vs. 去噪

初期的 NLP 迁移学习方法利用了 因果语言建模 目标 [6] 进行预训练。然而,随后显示去噪(也称为 掩码语言建模,或 MLM)目标表现更好 [5]。给定一组要作为输入传递给某些模型的文本标记,MLM 通过以下方式操作:

  1. 随机(均匀)选择 15% 的标记

  2. 用一个 [MASK] 标记替换 90% 的选择标记

  3. 用一个随机标记替换 10% 的选择标记

  4. 训练模型预测/分类每个 [MASK] 标记

被均匀选择的标记的百分比称为“损坏率”。在 T5 中,我们将看到这种去噪目标的几个不同变体,但基本想法保持不变。

“我们所有的目标都接收来自我们未标记文本数据集的一个标记化文本片段的标记 ID 序列。标记序列被处理以生成一个(损坏的)输入序列和相应的目标。然后,模型像往常一样通过最大似然法来预测目标序列。” — 来自 [1]

基准测试和评估

T5 尝试推导出 NLP 中迁移学习的最佳实践集。然而,为了确定哪些技术效果最佳,T5 在各种任务和自然语言基准上进行了评估。所有这些任务都是使用 T5 的 文本到文本格式解决的。有关这些任务的完整描述,请参见 [1] 的第 2.3 节。下面提供了简要总结。

值得注意的是,GLUE 和 SuperGLUE 基准测试中的所有任务都由 T5 连接在一起,并且在所有任务上同时进行微调。

其他重要观点

  • 不同类型的 Transformer 架构 [link]

  • 语言建模基础 [link]

  • 自注意力 [link]

我们从 T5 中学到了什么?

如前所述,T5 的实验尝试发现 NLP 中迁移学习的最佳实践。为此,首先提出一种基线方法,然后逐一更改该基线的几个方面(例如,模型架构/大小、数据集和预训练目标),以查看哪些效果最佳。这种方法类似于 坐标下降策略。我们将首先描述基线技术,然后解释 T5 在测试各种迁移学习设置后的发现。

T5 基线模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [11])

模型。T5 基础架构使用标准的编码器-解码器变换器架构;见上文。编码器和解码器的结构与BERTBase类似。尽管许多现代 NLP 方法使用“单堆栈”变换器架构(例如,仅编码器架构用于 BERT 或仅解码器架构用于大多数语言模型),T5 选择避免这些架构。有趣的是,[1]中的作者发现编码器-解码器架构在生成和分类任务中都取得了令人印象深刻的结果。[1]中没有考虑仅编码器模型,因为它们专门用于标记/跨度预测,不能很好地解决生成任务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

与编码器-解码器架构相比,仅解码器模型受到限制,因为它们仅使用因果(或掩码)自注意力;见上文。掩码自注意力在计算序列中任何给定标记的表示时只考虑前面的标记。然而,有些情况下我们希望对初始范围或文本前缀进行完全可见的注意力,然后基于这个前缀生成输出(例如,翻译任务)。仅解码器模型无法处理这些情况,因为它们对整个输入进行因果自注意力。

训练 T5。T5 模型在C4 语料库上进行了 34B 标记的预训练。作为对比,BERT 在 137B 标记上进行训练,而 RoBERTa 在 2.2T 标记上进行训练[5, 12]。受 BERT 中的 MLM 目标启发,T5 使用略微修改的去噪目标进行预训练:

  1. 随机选择输入序列中的 15%标记

  2. 用单一标记替换所有连续选择的标记范围

    “哨兵”标记

  3. 给每个哨兵标记一个在当前输入序列中唯一的 ID

  4. 使用所有选择的标记构造目标,用哨兵标记分隔

虽然这个任务看起来有点复杂,但我们可以在下面看到它在短输入序列上的工作示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

通过用单一的哨兵标记替换整个掩码标记的范围,我们降低了预训练的计算成本,因为我们通常在较短的输入和目标序列上进行操作。

微调。 在完成预训练后,T5 会在每个下游任务上单独进行微调,然后再进行评估。由于 T5 使用文本到文本的格式,预训练和微调都使用相同的 最大似然目标!换句话说,我们只需将正确答案表述为文本序列(在预训练和微调过程中),然后训练模型输出正确的文本序列。

基线表现如何? 如下表所示,基线 T5 模型的表现与之前的模型(如 BERT)相似,尽管这些模型并不可直接比较(即,基线 T5 模型使用的计算量是 BERTBase 的 25%)。此外,我们看到预训练在大多数任务上提供了巨大的好处。这个规则的例外是翻译任务,在这些任务中,预训练与未预训练的表现相似。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

寻找更好的方法…

在测试基线架构和训练方法后,[1] 的作者逐次修改这种方法的一个方面,例如底层架构、预训练目标或微调策略。通过测试这些不同的迁移学习变体,我们可以找到在不同语言理解任务中 consistently 表现最佳的方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

架构。 为了研究架构选择对迁移学习结果的影响,我们可以测试不同的 变体变换器架构。在 [1] 中测试的架构包括普通的编码器-解码器架构、仅解码器架构以及一个前缀语言模型,它在序列中对固定前缀执行完全可见的注意力,然后使用因果自注意力生成输出;见上文。这些架构之间的主要区别在于它们的自注意力机制中使用的掩蔽类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

当测试几种不同的架构(使用因果语言建模和去噪目标进行预训练)时,我们发现编码器-解码器变换器架构(具有去噪目标)表现最佳,因此在剩下的实验中采用了这种架构。相对于其他模型,这种编码器-解码器变体总共有 2P 个参数,但计算成本与具有 P 个参数的仅解码器模型相同。为了将总参数数量减少到 P,我们可以在编码器和解码器之间共享参数,发现这种方法表现非常好。

预训练目标。 最初,T5 使用三种不同类型的预训练目标进行训练。第一种是 BERT 风格的 MLM 目标。其他目标是一个去洗牌策略(即模型尝试将打乱的句子恢复到正确的顺序)和一个基于前缀的语言建模目标。在后者中,文本被分成两个跨度,第一个跨度作为输入传递给编码器,第二个跨度由解码器预测(即回忆一下我们使用的是编码器-解码器转换器)。下文比较了这些目标训练的模型的表现,我们可以看到去噪目标明显优于其他策略。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

从这里开始,[1]中的作者测试了对 BERT 风格 MLM 目标的几种修改,如下表所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

这些变体的表现趋于相似;见下文。然而,通过选择替换整个损坏令牌跨度为单个哨兵令牌的预训练目标,并且仅尝试预测目标中的损坏令牌,我们可以最小化预训练的计算成本。因此,遮蔽整个连续令牌跨度的基线策略是高效的,因为它产生了更短的目标序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

[1] 的作者测试了不同的损坏率,发现损坏率对结果没有显著影响,并且 15%的设置效果良好。还发现一种替代的预训练目标,即明确选择令牌跨度进行损坏(即基线方法选择令牌时采用均匀分布而不是跨度,然后将连续的令牌组合在一起),其表现与基线方法相似。下图展示了[1]中测试的不同预训练目标的示意图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

研究了许多不同的策略,但这里的主要结论是 (i) 去噪目标效果最好,(ii) 去噪目标的变体表现相似,以及 (iii) 最小化目标长度的策略在计算上最为高效。

数据和模型规模。 最后,研究了规模对 T5 质量的影响。首先,T5 使用几个不同的数据集进行预训练,包括一个未过滤的数据集,一个新闻特定数据集,一个模仿 GPT-2 的 WebText 语料库的数据集,以及几个维基百科语料库的变体。T5 在每个数据集上进行预训练后的表现如下面所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自 [1])

我们在这里看到 (i) 不过滤预训练语料库是极其有害的,(ii) 在特定领域语料库上进行预训练在某些情况下是有帮助的。例如,在基于新闻的语料库上进行预训练在 ReCoRD 这个基于新闻文章的阅读理解数据集上表现最佳。

“这些发现背后的主要教训是,在领域内未标记的数据上进行预训练可以提高下游任务的性能。这并不令人意外,但如果我们的目标是预训练一个能够快速适应来自任意领域的语言任务的模型,这种情况就显得不那么令人满意。” — 来源 [1]

进一步说,T5 使用不同大小的 C4 语料库的截断版本进行预训练。从这些实验中,我们了解到更多的数据(并不令人意外)更好。在预训练期间多次循环通过较小版本的数据集会导致过拟合,并损害下游性能;见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源 [1])

为了扩展 T5 模型,作者测试了以下修改:

  1. 4X 更多训练迭代(或 4X 更大的批次大小)

  2. 2X 更多训练迭代和 2X 更大的模型

  3. 4X 更大的模型

  4. 训练一个由 4 个编码器-解码器变换器组成的集合

这里,为了简化,预训练和微调步骤都增加了。这些实验的结果如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来源 [1])

这些结果大致符合我们的预期。增加训练时间(或批次大小)可以提高性能。将此与更大的模型结合起来,相比单独增加训练迭代或批次大小,能带来进一步的好处。换句话说,增加预训练数据量和模型大小在提升性能方面是互补的

“机器学习研究的痛苦教训认为,可以利用额外计算的通用方法最终会胜过依赖人类专业知识的方法” — 来源 [1]

其他内容。 T5 也使用不同的多任务训练策略进行了微调。总体而言,这些模型的表现略逊于那些针对每个任务单独微调的模型。然而,确实存在策略来最小化任务特定微调和多任务学习之间的性能差距。有关更多信息,请查看 此处 的概述。

许多深度神经网络的微调方法仅训练模型参数的子集(例如,“冻结”早期层并仅微调模型中的最后几层)。[1] 的作者尝试了几种这种微调 T5 的技术(例如,通过 适配器层 或逐步解冻 [6]),但这些方法被端到端微调完整模型所超越;见下文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(来自[1])

T5: 把一切整合在一起!

现在我们已经回顾了[1]中的整个实验分析,我们对 NLP 中的迁移学习不同选项以及什么效果最好有了更清晰的认识!下面,我们将讨论这一分析的主要要点,这些要点构成了 T5 所使用的官方迁移学习框架。与各种替代方案相比,这种方法被发现表现相当不错。

基线设置。 首先,让我们回顾一下 T5 的基线架构。它是一个编码器-解码器变换器,通过统一的文本到文本格式进行训练。在进行去噪预训练后,模型会在每个下游任务上单独进行微调,然后再进行评估。值得注意的是,最终的 T5 模型在 GLUE 和 SuperGLUE 基准测试中对每个任务进行了单独的微调,因为对所有任务同时训练的效果稍微差一点(假设我们采取必要的步骤以避免过拟合)。

预训练。 最终的 T5 方法并不是均匀选择标记,而是进行跨度破坏(即一次选择整个标记跨度进行破坏),平均跨度长度为三。然而,15%的标记仍然会被选择进行破坏。这个目标略好于基线,并产生更短的目标序列长度。此外,T5 将无监督预训练更新与多任务监督更新混合使用。无监督更新与监督更新的比例取决于所使用的模型大小(即,大型模型需要更多无监督更新以避免过拟合)。

训练量。 额外的预训练对 T5 的性能有帮助。具体来说,增加批量大小和训练迭代次数都能提升 T5 的性能。因此,最终的 T5 模型在总共预训练了 1T 标记。这比基线的 34B 标记要大得多,但仍远远低于在 2.2T 标记上进行预训练的 RoBERTa[12]。预训练是在通用的过滤 C4 数据集上进行的,因为特定任务的预训练在不同任务中没有一致的好处。

模型规模。 使用更大的模型是有帮助的,但有时较小的模型可能更合适(例如,当你在推理时计算资源有限)。因此,T5 发布了五种不同规模的模型,参数从 220M 到 11B 不等。因此,T5 实际上是一套不同的模型!我们可以通过链接这里访问这些模型。

结论

非常感谢阅读这篇文章。我是 Cameron R. WolfeRebuy 的 AI 总监。我研究深度学习的实证和理论基础。你还可以查看我在 medium 上的 其他文章!如果你喜欢这篇文章,请在 twitter 上关注我,或订阅我的 Deep (Learning) Focus 新闻通讯,在这里我通过对流行论文的易懂概述帮助读者建立对 AI 研究主题的深入理解。

参考文献

[1] Raffel, Colin, 等. “探索统一文本到文本转换器的迁移学习极限。” 机器学习研究杂志 21.1 (2020): 5485–5551。

[2] Liu, Peter J., 等. “通过总结长序列生成维基百科。” arXiv 预印本 arXiv:1801.10198 (2018)。

[3] Liu, Peter J., Yu-An Chung 和 Jie Ren. “Summae: 使用长度无关的自编码器进行零样本抽象文本总结。” arXiv 预印本 arXiv:1910.00998 (2019)。

[4] Song, Kaitao, 等. “Mass: 用于语言生成的掩码序列到序列预训练。” arXiv 预印本 arXiv:1905.02450 (2019)。

[5] Devlin, Jacob, 等. “Bert: 用于语言理解的深度双向转换器预训练。” arXiv 预印本 arXiv:1810.04805 (2018)。

[6] Howard, Jeremy 和 Sebastian Ruder. “通用语言模型微调用于文本分类。” arXiv 预印本 arXiv:1801.06146 (2018)。

[7] Wang, Alex, 等. “GLUE: 一个多任务基准和自然语言理解分析平台。” arXiv 预印本 arXiv:1804.07461 (2018)。

[8] Wang, Alex, 等. “Superglue: 一个更具粘性的通用语言理解系统基准。” 神经信息处理系统进展 32 (2019)。

[9] Hermann, Karl Moritz, 等. “教机器阅读和理解。” 神经信息处理系统进展 28 (2015)。

[10] Rajpurkar, Pranav, 等. “Squad: 100,000+ 个用于机器文本理解的问题。” arXiv 预印本 arXiv:1606.05250 (2016)。

[11] Vaswani, Ashish, 等. “注意力机制就是你所需要的一切。” 神经信息处理系统进展 30 (2017)。

[12] Liu, Yinhan, 等. “Roberta: 一种稳健优化的 BERT 预训练方法。” arXiv 预印本 arXiv:1907.11692 (2019)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值