DLAI-Jamba-笔记-全-
DLAI Jamba 笔记(全)
001:课程介绍与Jamba模型概述 🚀

在本节课中,我们将学习如何利用Jamba模型构建能够处理长上下文的AI应用。Jamba是一种创新的混合架构模型,它结合了Transformer和Mamba的优势,旨在高效处理超长文本输入。
课程概述
欢迎来到“使用Jamba构建长上下文AI应用”课程。本课程是与AI21实验室合作开发的。
Transformer架构是大多数大型语言模型的基础。然而,它在处理长上下文长度时效率不高。
Mamba是Transformer的一种替代方案,它能够通过读取任意长的上下文并将其压缩为固定大小的表示,来处理非常长的输入上下文。许多人一直对Mamba作为Transformer的可能替代品或继任者感到兴奋。
但研究人员发现,当上下文非常长时,纯Mamba架构表现不佳,因为其压缩机制会导致信息丢失。AI21实验室开发了一种新颖的Jamba模型,它结合了传统的Transformer和Mamba,以利用Mamba的效率,同时借助Transformer的注意力机制在正确的时间检索正确的信息。
核心架构对比
上一节我们提到了两种核心架构。本节中,我们来看看它们的具体特点。
Transformer的优势之一在于它会比较每一对输入标记,以查看它们彼此之间的关联程度。这就是注意力机制,它决定了在处理一个词时,模型应该关注句子中的哪些其他词。但这种方法在输入长度上具有二次方成本。尽管有多种技术可以降低这种成本,但处理非常长的输入上下文长度对Transformer来说仍然很昂贵。
然后,在论文《Mamba: Linear-Time Sequence Modeling with Selective State Spaces》中,作者描述了一种性能良好且可以在GPU上高效实现的现代状态空间模型。但Mamba在长距离关系和上下文学习方面不如Transformer。
Jamba模型作为一种混合的Transformer-Mamba架构,试图融合两者的优点。
课程讲师与内容
我们很高兴本课程的讲师是来自AI21实验室的首席解决方案架构师Chen Wang和AI技术负责人Ken Alphago,他们都是Mamba、Jamba和Transformer领域的专家。
我们很兴奋能在这里教授关于Jamba的课程。在课程中,我们将探索Jamba模型的基础结构,包括Transformer,但重点将放在该模型中鲜为人知的基于Mamba的方面,并理解这种混合架构为何有益。
您还将学习扩展语言模型上下文长度的策略,回顾评估长上下文模型的关键方面,并理解Jamba在这些场景中的优势。您将通过实践实验室获得使用Jamba的动手经验,包括提示工程、文档处理、工具调用和RAG应用,始终专注于利用Jamba模型的长上下文窗口优势来提升性能。
许多人参与了本课程的开发。我们要感谢来自AI21实验室的Ian Cox,以及来自DeepLearning.AI的Ashshmo Gagari和Jeff Ludwig。第一课将是Jamba模型的概述。
这听起来很棒。让我们继续观看下一个视频,学习关于Jamba的更多知识。
总结

本节课中,我们一起学习了Jamba模型的背景和核心概念。我们了解到,为了克服纯Transformer在处理长文本时的效率瓶颈和纯Mamba可能的信息丢失问题,Jamba创造性地将两者结合。在接下来的课程中,我们将深入其技术细节并动手实践。
002:Jamba模型概述 🚀
在本节课中,我们将学习Jamba模型的关键信息,包括其独特的架构和随之而来的优势。
开发动机
开发Jamba模型的主要动机是在不损害输出质量的前提下,提升大型语言模型的效率。目前几乎所有主流的LLM都采用Transformer架构。


它通过注意力机制保留所有上下文信息。其训练时间随上下文长度呈二次方增长。在推理时,每一步的时间随上下文长度线性增长(使用KV缓存),推理内存也呈线性增长。这种计算低效性在长上下文场景下代价高昂,并对上下文长度构成了限制。
Mamba架构简介
Mamba架构于2023年12月发布,旨在解决Transformer的计算效率问题。


它通过将上下文压缩成一个高效的状态(类似于循环神经网络),同时结合选择机制进行并行计算。更详细的讨论将在下一课进行。
与Transformer相比,Mamba架构带来了显著的效率提升:
- 训练时间:随上下文长度线性增长(Transformer为二次方增长)。
- 推理时间:每一步为常数时间(Transformer为线性增长)。
- 推理内存:保持恒定(Transformer为线性增长)。
这种大幅提升的计算效率使Mamba架构能够原生地更好地处理长上下文。
Jamba:混合架构的诞生
然而,纯Mamba架构模型的缺点是模型的鲁棒性和输出质量会在大规模应用时受损。

为了兼收两者之长,我们优化了Transformer和Mamba的混合架构,创造了Jamba模型,旨在实现高输出质量以及高计算效率(高吞吐量和低内存占用)。

Jamba模型还采用了混合专家(Mixture of Experts, MoE)技术,以进一步提升模型的吞吐量、效率和质量。

Jamba 1.5 模型家族

Jamba模型的最新版本是Jamba 1.5模型家族,包含两个模型:
- Jamba 1.5 Large:拥有940亿活跃参数和3980亿总参数。
- Jamba 1.5 Mini:拥有120亿活跃参数和520亿总参数。
两个模型都具有256K tokens的极长有效上下文长度。
开发者功能与可用性
Jamba模型为开发者构建企业级生成式AI应用配备了关键功能,例如:
- 工具调用(Tool Calling)
- 结构化JSON输出
- 文档作为输入对象
- 流式输出
Jamba模型也是多语言的,支持九种不同语言,包括英语、西班牙语、法语、葡萄牙语、意大利语、荷兰语、德语、阿拉伯语和希伯来语。
Jamba模型以开放权重形式在Hugging Face上发布,并广泛支持各种平台和框架,包括AWS、GCP、Azure、NVIDIA NIM、Databricks、Snowflake、LangChain、LlamaIndex等。您也可以将Jamba模型部署到您的私有云或本地环境中。
架构剖析与性能
深入内部结构,一个Jamba块由8层组成,包括:
- 1个Transformer层
- 3个Mamba层
- 4个Mamba + MoE层
这种组合优化了模型的输出质量和效率。


由于Mamba层的上下文压缩特性,Jamba模型在长上下文下的KV缓存内存占用优势非常明显。

在模型参数量相似甚至更小的情况下,Jamba模型的KV缓存仅为其他基于Transformer的LLM的一小部分。


长上下文评估基准

在保持高效率的同时,Jamba模型在长上下文评估基准测试中也表现出色。
RULER是NVIDIA最近开发的一个专门用于评估大语言模型长上下文性能的基准。它评估LLM在不同上下文长度下执行多种任务的能力,包括:
- 多针检索
- 多跳推理
- 关键词提取
- 问答
两个Jamba模型在不同上下文长度下都表现优异,其中Jamba 1.5在排行榜上名列前茅。
总结
本节课中,我们一起学习了关于Jamba模型的所有关键信息。现在你已经了解了Jamba模型的开发动机、其独特的混合架构(Transformer + Mamba + MoE)、模型规格、开发者功能及其在效率和长上下文性能上的优势。
接下来,你将学习导致Jamba模型开发的演进历程,以及其效率提升背后的科学原理。
下节课见!


003:3. Transformer-Mamba混合LLM架构


在本节课中,我们将学习如何使用AI21 SDK,特别是利用 documents 参数来处理长文档。

概述
在本节课中,我们将学习如何调用Jamba模型API,探索其核心参数,并重点掌握如何通过documents参数直接上传长文档进行处理。我们将使用英伟达近两年的10-K年报作为示例数据集,体验Jamba模型处理长上下文的能力。
Jamba模型API基础
与其他大语言模型API类似,Jamba模型API需要两个输入参数。
第一个参数是聊天消息列表。这包括系统消息、用户消息和助手消息,用于构成聊天历史。
第二个参数是模型名称。您可以选择使用 jamba-1.5-large 或 jamba-1.5-mini。您可以根据用例需求在质量、延迟和成本之间进行权衡。
此外,还有一组可选参数,可帮助您构建和定制复杂的生成式应用。
documents 是一个独特的参数,允许您在API调用中直接附加长文档作为输入对象。
您还可以强制模型以JSON格式响应,使用 tools 参数进行外部函数和工具调用。最大输出令牌数、温度(temperature)和Top-p等参数也可供您调整。
stop_sequence 在少样本或多样本上下文学习中非常有用。您还可以选择在一次API调用中生成多个响应,并流式传输响应(一次一个令牌),而不是等待整个响应完成。
准备环境与数据
在本课程中,我们将使用英伟达过去两年的10-K年报作为示例数据集。每份报告大约有10万个令牌,或大约200页。您可以充分利用Jamba模型的长上下文窗口来处理这些SEC申报文件。
如果您不熟悉SEC申报文件,不用担心,您很快就会自己找到答案。
现在,让我们进入笔记本,开始使用Jamba进行构建。
首先,添加这两行代码以忽略不必要的警告。
import warnings
warnings.filterwarnings('ignore')
现在,导入所需的库。您将加载AI21 Python客户端。同时,从Python客户端导入聊天消息和文档模式。
from ai21 import AI21Client
from ai21.models import ChatMessage, Document
您在本课中还需要API密钥,但请放心,API密钥已为您加载。在这里,您可以创建一个AI21客户端。
client = AI21Client(api_key='your_api_key_here')
现在,您已准备好使用Jamba模型。
发起基础请求
以下是一个聊天消息列表的示例,作为Jamba模型的输入。您可以在系统消息中为Jamba模型提供指导。您可以在用户消息中解释希望Jamba模型执行的任务。您可以在助手消息中附加Jamba模型之前的任何响应。
在这里,由于我们刚开始与Jamba模型交互,可以移除助手消息。
messages = [
ChatMessage(role="system", content="You are a helpful assistant."),
ChatMessage(role="user", content="Explain what SEC filings are in one short sentence.")
]
现在,在这个对Jamba模型的首次请求中,我们要求Jamba模型用一句话向我们解释SEC申报文件。
现在,让我们将消息发送给Jamba模型。您还可以自定义不同的可选参数。
response = client.chat.completions.create(
messages=messages,
model="jamba-1.5-large", # 您也可以选择使用更小更快的 `jamba-1.5-mini`
max_tokens=100,
temperature=0.4,
top_p=0.9,
stop=["\n\n"], # 停止序列可以是字符串列表
n=1 # 指定单次调用中生成的响应数量
)
我们选择使用Jamba-1.5-large模型,但您也可以选择使用更小更快的Jamba-1.5-mini。您可以自定义最大输出令牌数、温度(默认为0.4)和Top-p。还可以自定义停止序列。停止序列可以是一个字符串列表。当生成任何停止序列字符串时,响应将结束,并且停止序列不会包含在生成的响应中。例如,在停止序列中包含您多样本提示中的分隔符字符串,可以帮助模型在适当的位置停止。您还可以指定单次调用Jamba模型生成的响应数量。
现在,您可以运行此单元格以查看Jamba模型的响应。
print(response.choices[0].message.content)
解析响应
在响应中需要注意几个重要事项。首先,主要响应在助手消息内容部分。
因此,让我们看一下Jamba模型的响应。我们现在可以了解关于SEC申报文件的信息:SEC申报文件是美国上市公司必须向证券交易委员会提交的正式文件,提供详细的财务和运营信息,以确保透明度并保护投资者。
现在您知道了SEC申报文件的准确定义。
另一个需要注意的重要事项是使用信息部分中的令牌数量。
这里我们在提示中使用了26个令牌,在补全中使用了36个令牌,总共62个令牌。您可以通过每次调用Jamba模型来跟踪您的令牌消耗。
要显示响应消息的内容,您可以使用 response.choices[0].message.content 来仅获取响应字符串。
生成JSON格式响应
Jamba模型还可以生成指定JSON格式的响应。
现在,我们要求Jamba模型以JSON格式为我们提供前五种最常见SEC申报类型的信息,包括表格名称和描述。
messages_json = [
ChatMessage(role="system", content="You are a helpful assistant that outputs in JSON format."),
ChatMessage(role="user", content="List the top 5 most common types of SEC filings. For each, include the 'form_name' and a brief 'description'.")
]
response_json = client.chat.completions.create(
messages=messages_json,
model="jamba-1.5-large",
response_format={"type": "json_object"}, # 指定输出应为JSON对象
temperature=0 # 为确保输出一致性,可将温度指定为0
)
import json
print(json.dumps(json.loads(response_json.choices[0].message.content), indent=2))
现在,您可以在一个漂亮的JSON布局中打印模型输出。10-K表格(即年度报告)将在本课程中使用。其他流行的SEC申报类型还包括10-Q季度报告、8-K、S-1等。
让Jamba模型提供一致的JSON格式对于您的生成式应用的健壮性至关重要。
处理长文档
正如我们之前讨论的,Jamba模型的一个关键优势是其处理长上下文的能力。AI21 SDK还提供了一种便捷的方式,在API调用中将长文档附加到Jamba模型。
Jamba模型将根据提供的文档遵循您的要求或回答您的问题。为此,您可以首先加载两个英伟达10-K文件。
您也可以从纳斯达克网站下载英伟达10-K文件。原始文本文件可以使用AI21 SDK中的文档模式构建成文档对象列表。
# 假设已从文件加载文本内容到变量 nvidia_10k_2023_text 和 nvidia_10k_2022_text
documents = [
Document(
content=nvidia_10k_2023_text,
metadata={"company_name": "NVIDIA", "document_type": "10-K", "year": 2023}
),
Document(
content=nvidia_10k_2022_text,
metadata={"company_name": "NVIDIA", "document_type": "10-K", "year": 2022}
)
]
content 是您文件的文本。您还可以添加元数据,以进一步帮助Jamba模型智能地使用文档。例如,您可以添加公司名称、文档类型以及10-K申报年份到元数据中。
基于文档的查询
有了整整两年的10-K文档,您可以要求Jamba模型根据这两年的10-K申报文件生成一个包含信息的HTML表格。
请记住,现在包含了整整两年的10-K文档。Jamba模型正在处理大约20万个令牌。因此,此步骤可能需要一些时间。
messages_with_docs = [
ChatMessage(role="system", content="You are a helpful financial analyst."),
ChatMessage(role="user", content="Based on the provided 10-K documents, create an HTML table summarizing key financial metrics (e.g., total revenue, net income) for both years. Include the year in the table.")
]
response_with_docs = client.chat.completions.create(
messages=messages_with_docs,
model="jamba-1.5-large",
documents=documents,
max_tokens=500
)
print(response_with_docs.choices[0].message.content)
现在,我们可以使用IPython显示模块将其可视化。
from IPython.display import display, HTML
display(HTML(response_with_docs.choices[0].message.content))
现在我们有了这个漂亮的表格,让您可以轻松查看两年10-K申报的财务结果。
最后,在响应使用情况中,您实际上可以看到Jamba模型刚刚帮助您处理了超过20万个令牌,来自两年的10-K文件。
总结
在本节课中,我们一起学习了Jamba模型API的基本调用方法,包括必需参数和可选参数。我们重点实践了如何利用独特的documents参数直接上传并处理长文档(如英伟达的10-K年报)。我们还探索了如何让模型输出JSON格式以确保应用健壮性,并了解了如何解析响应和使用信息。
在下一节课中,您将学习关于Jamba模型的工具调用功能。我们下节课见。


004:Jamba的提示与文档处理


在本节课中,我们将深入探讨Transformer、状态空间模型及其演变过程。理解这些基础将有助于我们看清Jamba如何在其之上构建,并解决大语言模型架构中的关键挑战。

Transformer架构概述
上一节我们介绍了课程背景,本节中我们来看看Transformer架构的细节。Transformer是当前语言模型的主流架构。
该架构基于注意力机制,序列中的每个词元都会与所有其他词元进行交互,使模型能够捕捉词元之间的复杂关系。它会创建一个矩阵,将每个词元与其之前的所有词元进行比较。

矩阵中的权重由词元对之间的相关性决定。由于序列中所有词元之间的成对交互,其计算复杂度是二次的。
Transformer的推理过程

现在,让我们看看Transformer如何进行推理。在生成每个词元时,模型会计算序列中所有过去词元的注意力。每个生成的词元随后都会被包含在输入中,并为每个词元重复此过程。
为了避免在每一步生成时都重新计算所有先前词元的注意力,我们使用KV缓存。K缓存存储了先前词元在注意力计算中使用的向量表示,使我们能够专注于计算新词元的注意力。

使用KV缓存后,每一步的时间复杂度与序列长度呈线性关系,但整体上仍具有二次复杂度。然而,这种方法带来的代价是内存需求随序列长度线性增长。重新访问整个上下文会带来巨大的内存和计算需求,并导致推理速度变慢,难以扩展。

对于长序列,这些需求会造成重大限制。为了克服这一点,我们正在探索一种能更高效管理上下文的替代方法。
状态与状态空间模型
为了探索这种方法,让我们首先定义“状态”的概念。状态代表存储相关过去信息的内部记忆,帮助模型对未来词元做出准确预测。

不同的模型根据其架构以不同方式处理这种记忆。Transformer通过其注意力机制创建了一种状态形式。它们实际上记住了历史中的每一个细节,我们可以将KV缓存解释为Transformer的状态。然而,这种方法效率很低。
Transformer的一种替代方法是采用固定的状态表示。这些模型将过去信息压缩成一个固定且可管理大小的状态,并在每一步应用。例如,无论上下文是200个词元还是200,000个词元,它都被压缩成相同大小的状态。我们将这些模型称为基于状态的模型。
在推理过程中,基于状态的模型只需要处理先前的状态 H_{t-1} 和当前输入词元 x_t 来将状态更新为 H_t,然后生成下一个输出 y_t。接着重复相同的过程以生成未来的输出。
这种方法极大地减少了计算需求。它能随输入长度高效扩展,避免了计算的二次增长。具体来说,这种方法每一步需要恒定的推理时间,并且具有恒定的内存复杂度,不随序列长度变化。这比基于注意力的架构的时间和内存复杂度要高效得多。
循环神经网络
如果这个概念看起来很熟悉,那是因为它位于RNN(循环神经网络)的核心,这是一种实现固定大小状态概念的传统架构。
RNN的核心组件是循环单元,它包含一个作为模型内部记忆的隐藏状态。让我们看看使用RNN生成词元的过程。模型使用词元“jamba”作为输入来更新隐藏状态,然后生成输出词元。这个隐藏状态携带了所有先前词元的压缩信息,以帮助生成下一个词元。
这意味着无论序列长度如何,内存需求都是恒定的,且时间复杂度随序列长度线性增长,这要高效得多。然而,由于信息被总结成固定大小,RNN可能会失去捕捉长距离依赖关系的能力,使其效果不如Transformer。此外,由于时间步之间的依赖关系阻碍了并行化,它们的训练成本高昂,限制了训练效率。
以下是Transformer和RNN的对比:
- RNN:计算效率更高,但质量较低,且在训练时难以扩展。
- Transformer:质量高,但计算和内存效率低。
有趣的是,RNN在Transformer之前就已出现,但由于其缺点,它们未能完全实现状态模型的潜力。
结构化状态空间模型
结构化状态空间模型,也称为S4,提供了一种更有效的状态管理方式,通过对模型参数和处理状态施加某种结构,使用线性操作。
下图展示了S4模型如何进行推理。A_bar、B_bar 和 C 是模型在每一步使用的参数,用于在给定输入词元 x_t 的情况下生成输出词元 y_t。模型通过分别使用 A_bar 和 B_bar 线性组合先前状态和当前输入来更新其状态。A_bar 帮助确定随着时间推移,从状态中要忘记和记住什么;B_bar 帮助确定要从新输入中记住什么。更新状态后,模型使用 C 将当前状态映射到输出。C 帮助确定如何使用更新后的状态来生成下一个词元。
A_bar 和 B_bar 的形式依赖于一个名为 Δ(Delta)的参数,它代表步长。它本质上控制了依赖先前状态与当前输入之间的平衡。
S4模型的一个显著特点是其双重表示。它们既可以作为线性循环运行,也可以作为一维卷积运行。通过使用卷积,S4引入了在保持RNN高效推理的同时大规模训练LLM的可能性。
让我们回到与RNN的对比。S4在推理和训练上都很高效,这是它们相对于RNN的关键优势。然而,其质量仍然落后于Transformer。主要原因是S4中的状态与输入无关。让我们再次查看结构化S4的图示。A_bar、B_bar、C 和 Δ 都是学习到的常数。这意味着在每一步,模型都以相同的方式处理每一个输入。
再次考虑这个短语:“Jamba is hybrid.”。在结构化S4中,所有这些词元对模型将用于生成下一个词元的状态贡献相同。然而,词元“Jamba”和“hybrid”对于生成下一个词元更为相关。
选择性状态空间模型与Mamba
选择性S4通过使所有参数依赖于输入来解决这个问题。这种选择性概念使模型能够根据输入与任务的相关性来聚焦或过滤输入。因此,通过选择,状态变得更具表现力,在保持简洁的同时只关注最重要的细节。
Mamba是一种状态空间模型,它将选择性S4整合到一个循环架构中,根据当前输入选择性地处理信息。这种选择机制使Mamba具有上下文感知能力,使其能够自适应地确定哪些信息应存储在状态中以供未来预测。通过将结构化状态空间建模与选择性过滤过程相结合,Mamba在高效状态管理和目标信息保留之间取得了平衡。
现在,如果你查看Mamba论文,你会看到这张图,它比你目前看到的简化图示展示了更多细节。例如,A_bar_t 不仅依赖于我们之前讨论的 Δ_t,还依赖于另一个矩阵参数 A。在本课中,我们不会深入探讨 A 实际代表什么,但如果你想了解更多关于 Δ_t 和 A 如何与 A_bar_t 相关的信息,我鼓励你查看Mamba论文。
请注意选择机制如何专门应用于 Δ_t,这也间接影响了 A_bar_t。B_bar_t 依赖于两个参数 B 和 Δ_t。请注意选择机制如何应用于 Δ_t 和 B。最后,两个 C 是等价的。请注意选择机制也应用于 C。
然而,选择机制破坏了计算卷积的能力,而这正是结构化S4训练中实现并行化的关键。Mamba的另一个重要贡献是其在训练期间保持并行化的能力。这是通过应用并行扫描算法和硬件感知内存管理来实现的。

再次,我鼓励你查看Mamba论文以获取更多细节。最终,我们得到了一个强大的架构,在训练效率、推理速度和内存占用方面表现出色,同时还能提供高质量的性能。这就是为什么Mamba在Transformer力不从心的地方取得了成功,特别是在处理长上下文和实际生产工作负载方面。

Mamba的局限性与Jamba的诞生
但不幸的是,Mamba也有其缺点。当某些操作需要对特定词元进行仔细处理时,Mamba会表现不佳。隐藏状态的紧凑表示是不够的。


这时就需要注意力机制。一个例子是从上下文中复制特定的单词或句子。如这篇论文所示,Mamba在预测重复的单词序列方面不太成功。这是一个从输入中复制很重要的例子,Mamba的表现会比Transformer差。模型需要将电影评论分类为正面或负面。
这是一个示例输出。Transformer在此类任务中表现出色,不仅能成功识别评论的意图,还能输出正确的标签。然而,即使Mamba成功识别出正确的意图,它也经常输出一个不存在的标签,因为它没有关注上下文中找到的确切标签选项。

为了在获得这些架构优势的同时减轻其缺点,我们实现了自己新颖的架构,称为Jamba。Jamba代表“联合注意力与Mamba”,它结合了注意力层和Mamba层。

Jamba架构详解
在Transformer和Mamba组合的基础上,我们还使用了一项称为混合专家的附加技术,它允许我们在每个词元上仅使用一部分模型权重,这部分权重由路由器选择。每个这样的部分称为一个专家。这样,我们可以在不牺牲速度或成本的情况下提高质量。我们将Transformer、Mamba和MoE的组合称为Jamba块,它创建了一个强大而灵活的架构。
这种灵活性使Jamba能够平衡有时相互冲突的目标:低内存使用、高吞吐量和高质量输出。因此存在一个权衡:添加更多的Transformer层有助于解决我们讨论的Mamba问题,但也会增加复杂性。关键是找到最优的数量。
在我们进行的应用中,如论文中详述,我们发现7个Mamba层和1个注意力层的比例在质量和效率上达到了最佳平衡,同时在内存占用方面也高效得多。
回到我们的对比表格,我们可以看到Jamba实现了与Transformer相媲美的顶级性能,同时在所有方面都保持了高效率。通过基准测试来支持这一点,我们可以看到Jamba 1.5模型在常见的质量基准测试中取得了顶级分数。

此外,Jamba是所有主要竞争对手中最快的模型,在不影响性能的情况下为效率设定了新标准。

总结
在本节课中,我们一起学习了Jamba的Transformer、Mamba和混合专家组件的混合结构,使其能够自适应地管理资源,同时保持性能,使其成为可扩展语言建模的强大选择。


005:工具调用 🛠️

在本节课中,我们将学习Jamba模型的核心功能之一:工具调用。你将了解工具调用的概念、工作流程,并通过动手实践掌握如何让Jamba模型与外部函数和API协同工作。
概述

工具调用功能使Jamba模型能够与外部工具(如API或自定义函数)进行交互,从而获取实时数据或执行特定计算,以生成更准确、更丰富的回答。这对于构建功能强大的AI应用至关重要。
工具调用工作流程
上一节我们介绍了工具调用的概念,本节中我们来看看其具体的工作流程。
当用户向Jamba模型发送查询时,模型会判断是否需要使用可用的工具来提供最佳答案。如果不需要使用任何工具,Jamba模型将直接生成回复。如果需要使用工具,Jamba模型会根据用户查询,为正确的工具提取合适的参数。这些参数随后被用于调用工具,工具返回的结果会发送回Jamba模型,以生成最终的响应。
代码实践:算术工具调用
现在,让我们进入代码实践环节。首先,我们需要设置环境并导入必要的库。
import warnings
warnings.filterwarnings('ignore')
from ai21 import AI21Client
from ai21.models import Tool, ToolChoice
import os
# 设置API密钥并创建客户端
client = AI21Client(api_key=os.environ["AI21_API_KEY"])
我们知道,大语言模型并不擅长精确的算术计算。因此,我们可以为Jamba模型提供乘法(multiplication)和加法(addition)这两个算术函数,供其在需要时调用。
以下是这两个函数的定义:
def multiplication(a: float, b: float) -> float:
"""Multiply two numbers."""
return a * b
def addition(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
接下来,我们需要让Jamba模型知道这两个函数是可用的。我们可以使用AI21 SDK中的Tool定义来描述这些函数。
以下是定义工具的方法:
# 定义乘法工具
multiplication_tool = Tool(
type="function",
function={
"name": "multiplication",
"description": "Multiply two numbers together.",
"parameters": {
"type": "object",
"properties": {
"a": {"type": "number", "description": "The first number."},
"b": {"type": "number", "description": "The second number."}
},
"required": ["a", "b"]
}
}
)
# 定义加法工具
addition_tool = Tool(
type="function",
function={
"name": "addition",
"description": "Add two numbers together.",
"parameters": {
"type": "object",
"properties": {
"a": {"type": "number", "description": "The first number."},
"b": {"type": "number", "description": "The second number."}
},
"required": ["a", "b"]
}
}
)
# 将工具放入列表
tools = [multiplication_tool, addition_tool]
现在,让我们测试一个不需要调用工具的问题。
messages = [
{"role": "user", "content": "What is the capital of France?"}
]
response = client.chat.completions.create(
model="jamba-1.5-large",
messages=messages,
tools=tools
)
print(response.choices[0].message.tool_calls) # 输出应为 None
如你所见,对于“法国首都是什么”这个问题,模型没有调用任何工具,这是符合预期的。
现在,让我们问一个需要计算的问题。
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Please multiply 123 and 456 for me."}
]
response = client.chat.completions.create(
model="jamba-1.5-large",
messages=messages,
tools=tools
)
# 检查响应
assistant_message = response.choices[0].message
print(assistant_message.tool_calls)
在响应中,你会看到tool_calls部分包含了调用的函数名(multiplication)和参数({"a": 123, "b": 456})。这表明Jamba模型正确地识别出需要使用乘法函数。
以下是执行工具调用并获取最终响应的完整步骤:
# 1. 从模型响应中提取工具调用信息
tool_call = assistant_message.tool_calls[0]
func_name = tool_call.function.name
func_args = tool_call.function.arguments # 这是一个JSON字符串
# 2. 根据函数名调用对应的本地函数
import json
args_dict = json.loads(func_args)
if func_name == "multiplication":
result = multiplication(args_dict["a"], args_dict["b"])
elif func_name == "addition":
result = addition(args_dict["a"], args_dict["b"])
# 3. 将工具执行结果封装成消息
tool_message = {
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
}
# 4. 将初始的助手消息和工具消息一起发送回模型,获取最终回答
final_messages = messages + [assistant_message] + [tool_message]
final_response = client.chat.completions.create(
model="jamba-1.5-large",
messages=final_messages,
tools=tools
)
print(final_response.choices[0].message.content)
代码实践:调用外部API
除了自定义函数,工具调用更常见的用途是连接外部API。让我们看一个从美国证券交易委员会(SEC)获取公司10-Q季度报告摘要的例子。
首先,我们假设有一个能获取SEC文件的函数。
def sec_10q_fetch(ticker: str) -> str:
"""
Fetches the full text of the most recent 10-Q report for a given company ticker from the SEC website.
"""
# 这里是模拟实现。实际应用中,你会调用真正的SEC API。
# 例如,使用 `requests` 库访问 EDGAR 数据库。
return f"Full text of the most recent 10-Q report for {ticker}. (This is simulated content.)"
接着,我们为这个函数定义工具。
sec_tool = Tool(
type="function",
function={
"name": "sec_10q_fetch",
"description": "Fetch the most recent 10-Q filing for a public company by its stock ticker symbol.",
"parameters": {
"type": "object",
"properties": {
"ticker": {"type": "string", "description": "The stock ticker symbol of the company (e.g., AAPL, TSLA)."}
},
"required": ["ticker"]
}
}
)
tools_sec = [sec_tool]
现在,我们可以要求Jamba模型为我们总结一家公司最近的10-Q报告。
messages = [
{"role": "system", "content": "You are a financial analyst assistant."},
{"role": "user", "content": "Please summarize the most recent 10-Q report for Meta Platforms, Inc. (META)."}
]
response = client.chat.completions.create(
model="jamba-1.5-large",
messages=messages,
tools=tools_sec
)
# 检查模型是否调用了工具
assistant_message = response.choices[0].message
if assistant_message.tool_calls:
tool_call = assistant_message.tool_calls[0]
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
# 调用SEC函数
if func_name == "sec_10q_fetch":
sec_content = sec_10q_fetch(func_args["ticker"])
# 创建工具消息
tool_message = {
"role": "tool",
"tool_call_id": tool_call.id,
"content": sec_content
}
# 获取最终摘要
final_messages = messages + [assistant_message] + [tool_message]
final_response = client.chat.completions.create(
model="jamba-1.5-large",
messages=final_messages,
tools=tools_sec
)
print("Summary:")
print(final_response.choices[0].message.content)
通过这几行代码,Jamba模型就能够指向正确的函数,从SEC网站获取文档,并为你生成摘要。
总结
本节课中,我们一起学习了如何使用Jamba模型进行工具调用。我们了解了其工作流程,并通过算术计算和调用SEC API两个实例,掌握了定义工具、让模型识别工具、执行工具调用并整合结果生成最终响应的完整过程。这是构建能够与外部世界交互的AI应用的关键技能。

在下一节课中,你将学习如何扩展大语言模型的上下文窗口大小。
006:扩展上下文窗口大小 📈

在本节课中,我们将聚焦于长上下文能力。我们将探讨支持、训练和利用长上下文所需的条件,并学习评估长上下文模型的性能指标。
长上下文能力与应用场景 🚀
上一节我们介绍了课程概述,本节中我们来看看长上下文能力如何释放大型语言模型的全部潜力,使其在一系列复杂任务中表现出色。
以下是长上下文模型的主要应用场景:
- 文档处理与推理:在处理金融协议或法律合同等文档时,长上下文模型能保持关键上下文和细节,进行有效推理。
- 检索增强生成:在RAG流程中,长上下文模型增强了检索信息的整合能力,提高了找到既准确又上下文连贯的答案的几率。
- 多轮对话历史:这些模型可以保留多轮交互历史,确保对话的一致性和自然性。
- 上下文学习:与微调不同,我们可以将数千个示例直接嵌入上下文。这种方法成本效益高且灵活,无需重新训练即可快速适应新任务。
- 智能体与高级推理:长上下文模型对于智能体需求以及思维链等高级推理任务至关重要。它们可以支持决策制定和复杂问题解决所需的大量令牌选择。

训练长上下文模型的挑战 ⚠️
了解了长上下文的应用价值后,我们来看看训练一个长上下文模型面临的一系列重大挑战。
以下是训练长上下文模型的主要挑战:
- 巨大的计算成本:更长的序列会显著增加训练时间,仅使用长上下文数据训练模型会变得极其昂贵。
- Transformer架构的固有局限:作为大多数LLM的骨干,Transformer架构在扩展到长上下文时面临固有的限制。这些问题因计算瓶颈而加剧,GPU内存对模型能处理的上下文长度施加了严格限制。
- 数据挑战:没有足够自然产生的长上下文数据可用于有效训练。
- 长短上下文平衡:在训练期间平衡长上下文和短上下文是另一个关键障碍。过度强调长上下文可能会损害短上下文任务的性能,而过于依赖短上下文数据则会限制模型泛化到更长序列的能力。
- 评估困难:评估长上下文模型尤其具有挑战性。标准评估方法通常无法完全捕捉这些模型在真实场景中表现的复杂性。模型处理长上下文的能力并不一定等同于其在实践中有效利用这些信息的能力。
应对挑战的整体方案 🛠️

面对上述挑战,需要在架构、数据策略、训练基础设施与方法以及评估方法上进行创新。我们必须从各个方面着手,才能充分释放长上下文的潜力。

长上下文LLM的架构考量 🏗️
在探讨应对方案时,我们首先看看长上下文LLM的架构考量,了解推动进展的挑战与创新至关重要。
- 纯Transformer架构的局限:纯Transformer架构在扩展到长上下文时面临重大障碍。它们需要大量的内存和计算资源,这限制了其高效扩展的能力。虽然稀疏注意力等技术可以扩展上下文,但它们通常以质量下降为代价。
- Mamba架构的优势:为了克服这些限制,业界转向创新架构。Mamba架构效率极高,不仅因为它支持并行化,还因为其基于状态的设计显著降低了计算和内存复杂度。这种组合实现了更快的训练和更低的资源使用,使其特别适合处理长上下文。
- Mamba的潜在不足:然而,Mamba并不总能匹配Transformer的最高质量输出。例如,在需要整合整个上下文信息的任务中,Mamba可能难以有效压缩所有必要信息。
- Jamba混合架构:Jamba混合架构将Mamba与Transformer层集成,结合了Mamba的效率和扩展上下文能力,以及Transformer提供高质量响应的能力。这种协同作用确保了卓越的性能,同时保持了训练的计算效率和资源友好性。回到长上下文的例子,注意力机制可以被视为执行“检索电话簿”的功能,恢复在压缩过程中可能丢失的重要信息。
优化训练基础设施 ⚙️
为了应对长上下文训练日益增长的计算需求,调整基础设施以支持高级并行化至关重要。
以下是几种关键的并行化技术:
- 全分片数据并行
- 张量并行
- 序列并行
- 专家并行
其中,序列并行对于长上下文训练至关重要。它通过沿Transformer层的序列维度在多个GPU上分布计算和激活内存来工作。这种方法不仅减少了内存占用,还通过优化先前未被并行化的Transformer部分来提升性能。

数据收集与生成 📊
接下来我们讨论数据收集与生成。数据的质量直接影响长上下文模型的有效性。
我们主要关注两种关键的数据源类型:

- 自然长文档收集:例如书籍和代码库。这些来源提供了丰富、连续的上下文,与长上下文模型的需求高度契合,提供了深度和复杂性。
- 合成数据生成:通过生成多样且相关的数据来补充自然数据,我们可以填补空白,并进一步大规模地训练模型。
长上下文LLM的训练阶段 🧑🏫
在选择了架构、优化了基础设施并准备好数据之后,我们现在可以深入探讨训练过程。让我们从审视训练长上下文LLM的基本阶段开始。

这些阶段大致可分为预训练、中期训练和后训练。
- 预训练:模型学习预测序列中的下一个令牌,这使其能够深入理解语言和通用知识。
- 中期训练:在训练长上下文模型时,在预训练和后训练之间引入了一个中期阶段。在此阶段,预训练继续进行,但使用高比例的长文档,以强调模型的长程能力。此阶段结束时,我们得到一个长基础模型。
- 后训练:后训练通过在有监督微调数据上进行指令调优,使基础模型与人类指令对齐。在某些情况下,也会应用偏好优化来进一步提高性能。本节课我们只关注后训练阶段的SFT训练。
后训练的目标是同时实现两个目标:
- 第一,为模型提供技能和对话能力。
- 第二,保留预训练中获得的能力,特别是中期训练中发展的长上下文能力。
在此阶段结束时,我们得到一个长指令LLM,它能够遵循不同上下文长度的指令。
平衡长短上下文数据 ⚖️
在中期训练和后训练期间,平衡短上下文和长上下文数据是优化长上下文语言模型的关键。

在中期训练中,较高比例的长文档构建了长上下文能力,但纳入短上下文数据可确保模型保留处理短任务的多功能性。在后训练中,主要使用短上下文数据集会带来挑战,仅对短上下文数据进行微调可能会降低长上下文性能。仔细的数据混合和性能监控对于保持平衡至关重要。
现在,让我们探索另一种训练策略:长度课程学习。

长度课程学习策略 📚
长度课程学习是一种在模型训练期间逐步增加上下文长度的技术。
其核心理念是逐步扩展模型处理更长上下文的能力。例如,从静态的32K上下文窗口开始,然后逐步增加到64K、128K,依此类推。这种渐进式增加有助于模型适应处理更长的数据序列,同时保持其对较短上下文的理解。
以Llama预训练为例,上下文窗口从8K开始,分六个阶段逐步增加,最终达到128K。通过遵循这种方法,模型能够以可控的方式构建长上下文熟练度,确保在不同上下文长度下的稳定性和一致性能。

长上下文模型的评估 📋
回顾了训练方面后,我们现在转向长上下文模型的评估。全面的评估需要兼顾有效性和效率。

模型必须利用完整的上下文来产生高质量的输出,适当地利用和整合相关信息。另一方面,模型在实际使用中也必须高效。这意味着它在生成答案时不应太慢,并且在资源消耗上不应过于昂贵。
声明上下文长度 vs. 有效上下文长度 🔍
我们现在进入评估长上下文质量的一个重要区分:声明上下文长度与有效上下文长度。

- 声明上下文长度:指模型技术上可以无错误处理的最大输入长度,即模型的输入限制。
- 有效上下文长度:指模型仍能准确有效地执行任务、将相关信息整合到其输出中的最大输入长度。
理解这种区别很重要,因为长上下文能力不仅关乎处理更大的输入,还关乎模型利用这些输入中的信息产生高质量结果的能力。
综合评估基准 🎯
为了确保我们有效地评估长上下文模型,选择一个能真正捕捉模型在真实任务中能力的综合基准非常重要。
- Needle in a Haystack基准:这是一个传统的长上下文评估基准。它侧重于测试在长上下文中检索特定位置信息的合成任务,但可能无法完全捕捉现实世界应用的复杂性,使其对于实际用例来说不够全面。
- RULER基准:来自Anthropic的RULER基准是一个更强大的选择。该基准在四个对现实世界性能至关重要的关键领域评估长上下文模型:检索、多跳推理、聚合和问答。RULER基准也突出了声明上下文长度和有效上下文长度之间的区别。它将有效上下文长度定义为模型达到大于或等于85%准确率的最长上下文窗口,提供了一个更有意义、更实用的模型真实能力衡量标准。从这里我们可以看到,并非所有声明上下文长度都是真正有效的。然而,Jamba始终兑现其承诺的上下文长度。


效率评估指标 ⚡
现在,让我们转向长上下文模型的效率评估。评估效率时,我们关注两个关键方面:
- 延迟:LLM在收到查询后生成响应所需的时间。
- 吞吐量:LLM在给定时间内可以处理的查询数量。

优化延迟和吞吐量对于确保模型即使在重负载下也能保持响应迅速和高效至关重要。在延迟方面,随着上下文长度的增长,Jamba的表现优于竞争对手,显示出显著改进。在吞吐量方面,Jamba也处于领先地位。有趣的是,随着上下文长度的增加,Jamba与其他模型之间的性能差距会扩大。
总结 ✨

本节课中,我们一起学习了扩展LLM上下文窗口如何解锁新的应用并增强其在复杂、冗长输入上的性能。我们探讨了扩展上下文长度所涉及的关键挑战,并回顾了成功训练和评估这些模型所需的关键组件。通过优化架构、数据、训练和评估,我们正在推动LLM走向更广泛的高性能应用。
007:长上下文提示工程 🚀

在本节课中,我们将学习如何利用Jamba模型的长上下文能力,通过简单的提示工程来处理长文档。我们将探索如何将完整文档文本直接包含在提示中,并生成结构化输出。
概述

上一节我们介绍了如何扩展Jamba模型的上下文窗口。本节中,我们将采用不同的方法来处理贷款文档,即将完整文本包含在提示中,从而利用Jamba模型的长上下文能力。这种方法与使用document参数的效果非常相似。
以下是几种可以考虑在提示或document参数中包含长上下文的场景:
- 例如,总结一份完整的长文档以提取见解。
- 比较多个文档。
- 分析长聊天记录或通话记录,其中相关信息可能分散在整个内容中。
- 在涉及多步推理的系统中,当您有包含多轮工具调用消息的长聊天历史时。
现在,轮到您来处理一些示例了。
准备工作
首先,执行两行快速代码以忽略任何不必要的警告。
import warnings
warnings.filterwarnings('ignore')
导入与之前实验相同的库,并加载已为您设置好的API密钥,然后创建AI21客户端以开始工作。
import os
from ai21 import AI21Client
client = AI21Client(api_key=os.environ.get("AI21_API_KEY"))
您可以加载我们在之前实验中用过的Nvidia 10-K文件。
# 假设已定义加载文件的函数
nvidia_10k_2024 = load_nvidia_10k_2024()
基础长上下文问答
现在,您可以要求Jamba模型帮助您处理2024年的Nvidia 10-K文件(这是一个非常长的文件),只需使用简单的系统消息和提示,而无需进行任何分块处理。
为了使操作更简单,您可以创建一个简单的函数来直接与您的文档聊天。
def jamba_chat(system_message, user_message, document_text):
messages = [
{"role": "system", "content": system_message},
{"role": "user", "content": f"Document: {document_text}\n\nQuestion: {user_message}"}
]
response = client.chat.completions.create(
model="jamba-1.5-mini",
messages=messages,
max_tokens=500
)
return response.choices[0].message.content
在这个jamba_chat函数中,Jamba模型的任务是基于提示中提供的文档来回答您的问题。在您的工作流程中,数据中心系统和产品是主要的驱动因素。
生成结构化JSON输出
对于从大模型获取结构化输出,JSON格式通常是必要的。类似于jamba_chat函数,您可以创建这个jamba_json函数。
def jamba_json(system_message, user_message, document_text, json_schema):
messages = [
{"role": "system", "content": system_message},
{"role": "user", "content": f"Document: {document_text}\n\nInstruction: {user_message}"}
]
response = client.chat.completions.create(
model="jamba-1.5-mini",
messages=messages,
response_format={"type": "json_object", "schema": json_schema},
max_tokens=1000
)
return response.choices[0].message.content
在jamba_json函数中,您在系统消息和提示中提供指令,并在Jamba模型调用中的response_format参数里指定JSON对象。
现在是时候编写您的查询,要求Jamba模型为您创建JSON输出了。
# 定义查询和JSON模式
query = """
请从提供的10-K文件中提取以下财务信息。
"""
json_schema = {
"type": "object",
"properties": {
"fiscal_year_end_date": {"type": "string"},
"revenue": {"type": "number"},
"gross_profit": {"type": "number"},
"net_income": {"type": "number"},
"earnings_per_share": {"type": "number"},
"revenue_by_segment": {"type": "object"},
"revenue_by_georegion": {"type": "object"}
},
"required": ["fiscal_year_end_date", "revenue", "gross_profit", "net_income", "earnings_per_share"]
}
# 调用函数
json_response = jamba_json(
system_message="你是一个财务分析助手。请严格根据提供的文档回答问题。",
user_message=query,
document_text=nvidia_10k_2024,
json_schema=json_schema
)
print(json_response)
在这个例子中,我们要求Jamba模型生成JSON输出,包含财年结束日期、收入、毛利润、净收入、每股收益、按业务部门的收入以及按地理区域的收入。您可以将查询和文档发送到jamba_json函数,现在Jamba模型已经以JSON格式为您提供了答案。
跨多文档分析
正如我们在前面课程中讨论的,借助长上下文窗口,您可以包含多个长文档,并要求Jamba模型根据提供的所有文档提供答案。
例如,我们可以合并2023年和2024年的10-K文件,并传递给jamba_chat函数。
# 加载2023年文档
nvidia_10k_2023 = load_nvidia_10k_2023()
combined_docs = nvidia_10k_2023 + "\n\n---\n\n" + nvidia_10k_2024
comparison_query = """
请比较2023年和2024年Nvidia 10-K文件中的关键财务数据。
请生成一个包含以下信息的HTML表格:财政年度、总收入、毛利润、净收入、研发费用。
"""
html_table_response = jamba_chat(
system_message="你是一个数据分析师,擅长比较和总结财务信息。",
user_message=comparison_query,
document_text=combined_docs
)
在您请求创建包含以下财务信息的HTML表格后,您可以使用IPython的显示模块来呈现HTML表格。
from IPython.display import HTML
HTML(html_table_response)
总结

本节课中,我们一起学习了如何使用Jamba模型通过简单的提示工程来处理长文档。我们实践了将完整文档放入提示的直接方法,创建了用于问答和生成JSON输出的辅助函数,并探索了如何利用长上下文能力来分析和比较多个文档。在下一课中,您将使用RAG工具进行更深入的实践。
008:对话式RAG与自定义RAG管道构建 🧠

在本节课中,我们将学习如何使用AI21的对话式RAG工具,并构建一个自定义的RAG(检索增强生成)管道来处理长文档。我们将探索如何利用Jamba模型的长上下文窗口来提升RAG应用的性能。

概述
在之前的实验中,我们已经学习了如何使用Jamba模型通过document参数或在单个提示中处理长文档。然而,根据不同的用例和数据,您可能需要考虑将Jamba与RAG管道结合使用,以在响应质量、延迟、成本等关键指标之间取得平衡。Jamba模型的长上下文窗口可以有效提升RAG管道的性能。
提升RAG性能的潜在方法
Jamba的长上下文能力可以通过以下几种方式优化RAG管道:
- 我们可以包含更多数量的最相关检索片段。
- 我们可以使用更长的文本片段。
- 我们可以将长的多轮对话历史包含进来。
- 我们可以利用包含相邻片段或完整文档的检索策略。
在本实验中,我们将通过两种不同的方式使用Jamba构建RAG管道。首先,我们将使用AI21构建的一个开箱即用的RAG工具——AI21对话式RAG。然后,我们将使用LangChain和AI21 Jamba模型构建一个简单的RAG管道来结束本课程。
AI21 对话式RAG架构解析
在开始使用AI21对话式RAG之前,让我们先了解其工作原理。
整个流程始于用户查询,该查询与聊天历史记录结合后被发送到执行引擎。执行引擎会判断当前查询是否需要额外的组织数据来回答。
如果不需要,查询和聊天历史将直接发送给LLM(本例中为Jamba)以生成答案。如果需要额外的组织数据,用户查询将被提取并“去语境化”,形成一个独立的、用于检索相关片段的问题。
检索完成后,查询和检索到的文本片段将被用于生成一个“有根据的”答案。为了进一步提高答案的准确性和质量,系统会使用一个“评判”模型来验证生成的答案。如果原始答案未通过验证,将触发重新生成。最后,经过验证的答案将与聊天历史记录“再语境化”,并连同引用一起发送回给用户。
总而言之,AI21对话式RAG是一个易于使用的开箱即用RAG引擎,同时其每个步骤的参数也是可定制的,例如:
- 检索片段的最大数量。
- 检索阈值。
- 检索策略和搜索方法。
- 使用完整的对话历史来生成响应,以实现多轮问答体验。
现在,让我们深入实验,通过代码查看一切是如何运作的。
实验:使用AI21对话式RAG
与之前的实验一样,我们首先使用这两行代码来忽略不必要的警告。
首先,导入AI21库并加载API密钥以创建AI21客户端。API密钥已为您设置好,无需担心。
AI21对话式RAG主要需要您提供两样东西:您希望答案基于的文档,以及您想问的问题。本例将使用2024年英伟达10-K年度收益报告。要上传文件到对话式RAG,我们可以从工具中导入文件上传函数。文件已为您上传,因此您可以跳过此步骤。如果您上传了自己的文件,请在使用完毕后记得用这两行代码删除它。
一旦文件与对话式RAG共享,索引过程将自动为您完成。
现在,您可以使用conversational_rag_response函数来发送查询。这个简单的函数会附加每一轮的用户查询和助手响应,并包含整个聊天历史记录,为您的查询提供更多上下文。这里,我们只返回LLM的响应。您也可以从AI21对话式RAG获取引用,包括检索到的文本片段及其所在文件。
如果您想调整任何RAG参数,例如检索片段的最大数量、检索阈值和策略、搜索方法、每个步骤的LLM选择、模型温度和提示模板等,请随时在工具文件中进行更改。
现在,是时候开始提问了。假设您只想快速获取这份10-K文件的摘要。
您可以继续跟进并提出更详细的问题。如果您问了一个文档无法回答的问题,例如询问一项投资决策,对话式RAG将不会为您提供答案。
为了让实验更有趣,您可以在Notebook中部署一个Gradio应用,开始与AI21对话式RAG聊天。要创建Gradio应用,您可以将函数指向我们之前定义的conversational_rag_response函数,并添加一些预填充的示例。
尽管对话式RAG不会直接为您做出投资决策,但您仍然可以使用它来提取非常具体的财务信息,以帮助您做出明智的投资决策。例如,您可以询问英伟达在可持续发展方面采取的行动,并快速从中获得答案。
现在,您可以快速阅读关于英伟达可持续发展倡议的内容。您也可以了解公司的风险、资本配置、现金流等方面。或者,您也可以添加自己的问题。
构建自定义RAG管道
好了,为了结束本课程,您将使用LangChain和AI21 Jamba模型创建一个简单的RAG管道,在这里您可以自定义管道中的每一步。
使用LangChain构建RAG管道需要准备几样东西:
- 您需要一个LLM,这里将是AI21 Jamba模型。
- 您需要为文档建立索引,这包括文本分块、嵌入模型以及用于存储嵌入向量的向量数据库。
- 当您提出包裹在提示模板中的问题时,最相关的文本片段将被用来帮助回答问题。
让我们开始吧。首先,选择Jamba 1.5 Large模型作为LLM。然后,加载英伟达10-K文件。将文档分割成较小的块,每个块2000个令牌,重叠400个令牌。
下一步,您将使用来自Hugging Face的嵌入模型和Chroma向量数据库。至此,索引部分已经完成。
这里有一个简单的提示模板,您可以用它来向Jamba模型提供指令,并将您的文本和问题包含在内。您可以用自己的指令自定义这个提示模板。
为了检索最相关的文本片段,您将使用最大边际相关性检索器,并检索前10个最相关的片段。
好了,我们已经到了构建您自己的RAG管道的最后一步。使用LangChain,您可以将每个组件(包括检索器、提示和LLM)缝合在一起,创建您自己的RAG链。现在,您的RAG管道已经准备好回答问题了。
如果您想查看RAG管道中检索到的所有文本片段,您也可以查看检索器针对您的问题返回的结果,以查看为您检索到的所有文本片段。如果您有一系列问题要问,您可以批量发送您的问题列表,一次性获取所有答案。
完成本课程后,别忘了清理向量数据库。
总结
在本节课中,我们学习了如何使用AI21对话式RAG,以及如何使用LangChain和Jamba模型构建RAG管道。至此,我们的课程结束。
通过本课程,您学习了三种使用Jamba处理长文档的不同方法:
- 您可以在提示中包含整个长文档的文本。
- 您可以使用
document参数附加文档。 - 您可以使用不同的RAG工具,包括AI21对话式RAG。

我鼓励您使用自己的文档,结合在整个课程中学到的不同技术和工具,构建您自己的生成式AI应用。
009:总结 🎯

在本课程中,我们学习了Jamba架构,探讨了其在长上下文处理与效率方面的优势。
课程回顾 📚
上一节我们介绍了Jamba模型的工具调用功能。现在,让我们对整个课程内容进行总结。
以下是本课程涵盖的核心知识点:
- Jamba架构:我们了解了Jamba的混合模型设计,它结合了Transformer和状态空间模型(SSM) 的优势,其核心思想可以概括为
Jamba = Transformer + SSM。 - 长上下文与效率优势:Jamba能够高效处理超长文本序列,同时保持较低的计算和内存开销。
- 处理长文档的方法:你学习了使用Jamba模型处理长文档的多种方式。
- 文档参数:将整个文档作为输入参数。
- 上下文学习:在提示中提供示例,让模型学习并完成任务。
- 检索增强生成:结合外部知识库来获取相关信息,再生成答案。
- 工具调用:你掌握了如何让Jamba模型与外部工具或API进行交互,以执行特定操作。
结语 🚀
本节课中,我们一起学习了Jamba模型的核心架构、其处理长上下文的强大能力,以及如何通过多种方式(包括工具调用)来构建实际应用。我们期待看到你运用Jamba模型,构建出属于自己的创新AI应用。


浙公网安备 33010602011771号