跳至主要内容

Mixtral 8X22B 入门指南

探索 Mistral AI 的 Mixtral 8X22B 模型如何凭借高效的 SMoE 架构,重塑大语言模型范式,带来更卓越的性能与可扩展性。
· 12分钟 阅读

使用 AI 探索

当 OpenAI 在 2022 年发布 ChatGPT 时,很多人都在想,其他公司是否还能与这样一款由微软这样的大厂支持的优质产品竞争。在大家都将目光投向 Google 和 Meta 等科技巨头时,Mistral AI 于 2023 年推出了其 7B 模型,以几乎两倍的规模超越了所有开源 LLM。

自那以后,Mistral AI 成为了 LLM 竞赛中的重要玩家。2024 年 4 月,他们发布了 Mixtral 8X22B,该模型在许多基准测试中轻松超越了当时最强的开源 LLM——Llama 2。

在本教程中,我们将详细介绍 Mixtral 8X22B 模型,从其架构到底层原理,并讲解如何基于它搭建 RAG 流水线。

Mixtral 8x22B 模型的独特之处是什么?

Mixtral 8X22B 是 Mistral AI 最新发布的模型。它采用稀疏专家混合(SMoE)架构,拥有 1410 亿参数。正是这种 SMoE 架构带来了诸多优势。SMoE 是一种神经网络形式,它针对不同任务使用不同的小模型(专家),并只激活所需专家,以节省时间与算力。

首先,就同等规模而言,该模型在成本效率上无可匹敌,提供了开源社区中最佳的性能/成本比:

image.png

上图列出了部分领先的开源 LLM 以及它们为达到某一性能阈值所需的有效参数数。Mixtral 位于左上角,这意味着与同一量级的模型(如 Command R+)相比,它使用显著更少的参数便能达到 75% 以上的性能。

尽管 Mixtral 8X22B 拥有 1410 亿参数,但其稀疏激活模式在推理时仅使用 390 亿参数。这使它的性能和速度都优于任何 700 亿参数的致密模型,比如 Llama 2 70B。它还支持 64k 令牌上下文窗口,这在当今的开源 LLM 中非常罕见。

此外,该模型采用最宽松的开源许可——Apache 2.0。结合其较低的运行成本,Mixtral 8X22B 非常适合用于微调场景。

Mixtral 8X22B 基准测试

Mixtral 8x22B 在行业标准基准测试中表现出色。在多数测试中,重点对比了它与同类主要替代方案的表现:

  • Llama 70B:由 Meta 提供,适用于大规模语言建模、文本生成和对话系统。
  • Command R+:Cohere 提供的 104B 参数模型,专为长上下文任务和 RAG 流水线设计。

例如,Mixtral 8X22B 能够熟练使用五种语言:英语、德语、法语、西班牙语和意大利语。证据见下表:

image.png

在以下三项语言任务基准上,它都击败了 Llama 2 70B:

  • Arc-C:Abstraction and Reasoning Corpus(抽象与推理语料库)基准,用以衡量 AI 在常识推理方面的表现。
  • HellaS:HellaSwag,是另一个常识推理基准。
  • MMLU:大规模多任务语言理解基准。

在英语的纯常识推理与知识问答方面,Mixtral 再次表现不俗:

image.png

在两项基准上略逊于 Command R+,但在其他方面显著更强。

而其最具代表性的亮点——Mixtral 8X22B 在数学与编码任务上全面压制其替代方案:

image.png

接下来,我们来看一看该模型如何实现其先进性能。

Mixtral 8X22B 背后的架构——SMoE 解析

为更好地理解稀疏专家混合(SMoE)架构,我们用一个简单的类比:假设有 100 人在做一个项目。

  • 传统模型:整支团队(全部模型参数)分析项目的全部信息,所有人一起处理每个任务。
  • SMoE 架构:一位聪明的团队负责人会根据专长分配任务。负责人(称为路由器或门控网络)会将每条信息(令牌)分配给最适合处理它的一小组专家。只有合适的专家参与问题处理,使过程更快、更聚焦。

SMoE 模型包含以下关键组件:

  1. 专家:相对于完整模型而言更小的神经网络。Mixtral 使用 8 个专家,每个专家处理特定类型的信息或任务。例如,有的专家负责数学与逻辑查询,另一个则可能负责法语。
  2. 路由器(门控网络):门控网络决定将哪些令牌发送给哪个专家。路由器通常本身也是一个小型神经网络,会综合考虑令牌内容与当前上下文来做出决策。如何将令牌路由到专家,是使用任何 MoE 模型时的一项重大抉择。
  3. 聚合:专家处理完其分配的令牌后,会对输出进行合并。这可以通过简单平均或更复杂的加权策略等多种方式完成。

这种模型结构具有多方面优势:

  • 高效:每次输入只激活少量专家,SMoE 能降低计算成本并提升处理速度。
  • 可扩展:可以轻松为专家池增加新专家,而不会显著影响训练或推理时间,从而在保持高容量的同时构建超大模型。
  • 准确:针对特定任务的专家化有助于相较单一的整体网络获得更好的表现。基准测试显示,Mixtral 在语言、数学和编码任务上尤其出色,这很可能要归功于其专门化的专家。

不过,作为新兴架构,SMoE 模型也带来了尚未被充分解决的独特挑战:

  • 训练复杂:由于门控网络和专家之间的协同带来额外复杂度,训练 SMoE 模型可能非常困难。
  • 寻找合适专家:确定专家的数量与类型对性能至关重要。
  • 内存占用重:受架构影响,推理时必须将模型的全部参数加载到内存中,耗尽 GPU 显存。要运行 Mixtral 8X22B 的推理,至少需要 300GB 显存的 GPU。

Mixtral 8X22B memory usage

总之,由于模型规模是提升模型质量的关键因素之一,减少有效参数数量能显著降低训练成本并加速训练。在计算预算受限时,训练一个更大的模型但用更少的步数,往往比用更多步数训练一个小模型更划算。

专家混合架构能以远低于致密模型的算力完成训练,从而在相同预算下大幅扩大模型规模。任何 SMoE 模型在预训练阶段,都应能比其致密对应模型更快达到同等质量。

Mixtral 8x22B 上手指南

本节我们将学习如何使用 Mistral API 来调用 Mixtral 8X22B。由于该模型约 80GB,且需要 300GB 显存的 GPU,在云端运行成本较高,更别说在消费级硬件上了。

账号设置

Mistral AI 要求您创建账户并填写结算信息以获取 API 密钥。请访问 mistral.ai 创建账户。使用凭据登录后,您会被引导至位于 console.mistral.ai 的 Mistral 控制台。

Mixtral 8X22B sign 
-up

接着,前往“Billing”,添加您的付款信息:

Mixtral 8X22B payment

然后,充值一定额度:

Mixtral 8X22B add credits

这将允许您在“API KEYS”部分生成 API 密钥:

Mixtral 8X22B API key

创建密钥后只会显示一次,请妥善保存。我们会在下一节用到它。

环境配置

现在,我们来创建一个虚拟环境以运行 Mistral API。这里使用 Conda:

$ conda init  # Run if your Conda executable is new
$ conda env create -n mistral python==3.8 -y
$ conda activate mistral

然后,安装 mistralai Python 包以及其他几个必需组件:

$ pip install mistralai
$ pip install python-dotenv ipykernel
$ ipython kernel install --user --name=mistral

最后一条命令会将新建的 Conda 环境添加为一个 Jupyter 内核。

我们将使用 python-dotenv 包,在笔记本中安全读取 Mistral API 密钥。为此,请在工作目录创建一个 .env 文件:

$ touch .env

然后,按如下语法在文件中写入您的密钥:

MISTRAL_API_KEY=YOUR_KEY_HERE

另外,请务必将 .env 文件添加到 .gitignore,避免意外泄露到 GitHub:

$ echo ".env" >> .gitignore

现在,我们可以使用 load_dotenv 函数与 os 库来读取刚保存的密钥:

import os
from dotenv import load_dotenv

load_dotenv()

api_key = os.getenv("MISTRAL_API_KEY")

使用聊天客户端

最后,为与任一 Mistral 模型交互,我们将使用 MistralClient 对象:

from mistralai.client import MistralClient

client = MistralClient(api_key=api_key)

客户端需要我们的 API 密钥来连接 Mistral 服务器。随后,我们引入 ChatMessage 类来与 Mistral 模型进行对话:

from mistralai.models.chat_completion import ChatMessage

model = "open-mixtral-8x22b"

message = "Who is the best French football player of all time?"

chat_response = client.chat(
   model=model,
   messages=[ChatMessage(role="user", content=message)],
)

print(chat_response.choices[0].message.content[:300])
Determining the "best" French football player of all time can be subjective and depends on personal opinion. However, one player who is often mentioned in this context is Zinedine Zidane. He had an impressive career both for the French national team and at club level. He was a key player in France's

我们得到了响应——说明一切设置正确。

ChatResponse 对象通常包含不止一个答案,这里我们选择第一个,并打印其部分内容。

Mixtral 8X22B 的实用场景

除了纯文本生成,您还能用 Mixtral 做更多事情:

  • 生成嵌入向量
  • 创建同义改写检测器
  • 完整的 RAG 流水线
  • 函数调用

等等。我们将逐一介绍这些场景。

文本生成

在上一节,我们已经能通过聊天客户端生成大段文本。在一些情况下,当我们预期答案较长时,像 ChatGPT 那样以流式方式输出更合适。Mixtral 同样支持:

messages = [ChatMessage(role="user", content="What led to Zidane's ban from football?")]

# With streaming
stream_response = client.chat_stream(model=model, messages=messages)

for chunk in stream_response:
   print(chunk.choices[0].delta.content, end="")

我们可以使用 chat_stream 代替 chat 方法,它会按需分块返回答案:

Mixtral 8X22B text streaming

生成嵌入向量

嵌入向量 是 LLM 应用的关键组成部分。嵌入是文本在高维向量空间中的向量表示,通过其位置捕捉语义。如果两个嵌入之间的距离较近,则表示语义相似。例如,在嵌入空间中,apple 会比 keyboard 更接近 orange。

Mistral API 提供了最先进的文本嵌入模型。我们简单看一下如何使用:

to_embed = ["Is Messi better than Zidane?", "How about Ronaldo?"]

embeddings_batch_response = client.embeddings(
   model="mistral-embed",
   input=to_embed,
)

type(embeddings_batch_response)
mistralai.models.embeddings.EmbeddingResponse

首先,我们在 to_embed 中创建一个待嵌入的句子列表。然后调用 embeddings 方法并指定嵌入模型名 mistral-embed。结果是一个 EmbeddingResponse 对象。打印其 data 属性的长度,会发现针对两个句子返回了两个向量:

len(embeddings_batch_response.data)
2

我们还可以查看向量的维度:

first_sentence = embeddings_batch_response.data[0]

len(first_sentence.embedding)  # Embedding dimension
1024

得到的结果为 1024,表示 Mistral 会将任意长度的文本嵌入为 1024 维向量。

请注意,更高维度的嵌入可能更好地捕捉文本信息并提升性能,但在托管与推理时需要更多算力。

尽管本节没有使用 Mixtral 8X22B 模型,但理解嵌入向量对于稍后搭建 RAG 流水线非常重要。

使用嵌入向量进行同义改写检测

如前所述,如果两个嵌入的距离较近,则它们可能在语义上相近。基于此,我们可以构建一个简单的同义改写检测器:如果两句子的距离很小,它们就可能是彼此的同义改写。

首先,我们编写一个函数,返回给定输入的嵌入向量:

def get_text_embedding(input, client):
   embeddings_batch_response = client.embeddings(
model="mistral-embed", input=input
)

   return embeddings_batch_response.data[0].embedding

然后,定义一组要相互检测是否为改写的句子,并获取它们的嵌入:

sentences = [
   "What led to Zidane's ban from football?",
   "This is a totally different sentence.",
   "What caused Zidane to get banned from football?",
]

sentence_embeddings = [get_text_embedding(t, client) for t in sentences]

接着,使用 itertools 生成所有可能的两两句子组合:

import itertools

sentence_embeddings_pairs = list(itertools.combinations(sentence_embeddings, 2))
sentence_pairs = list(itertools.combinations(sentences, 2))

print(sentence_pairs[0])
("What led to Zidane's ban from football?", 'This is a totally different sentence.')

然后,打印每对句子嵌入之间的欧氏距离:

from sklearn.metrics.pairwise import euclidean_distances

for s, e in zip(sentence_pairs, sentence_embeddings_pairs):
   distance = euclidean_distances([e[0]], [e[1]])

   print(s, distance)
("What led to Zidane's ban from football?", 'This is a totally different sentence.') [[0.84503319]]
("What led to Zidane's ban from football?", 'What caused Zidane to get banned from football?') [[0.28662641]]
('This is a totally different sentence.', 'What caused Zidane to get banned from football?') [[0.83794058]]

第二对的距离更近,表明它们可能是彼此的改写。

在 RAG 流水线中使用 Mixtral 8X22B

LLM 虽然训练于海量数据之上,但并非总是最新,也无法访问您的私有数据集。如果只是希望模型能回答关于现有数据集的问题,对其进行微调往往代价高昂。

这就是检索增强生成(RAG)流水线流行的原因。无需昂贵的微调,您就可以让 LLM 处理其训练语料之外的自定义信息,并基于此作答。

本节我们将构建一个基础的 RAG 流水线,学习这篇1440 文章中来自昨天的新闻。我已将部分新闻保存到这个文本文件,您可以从我的 GitHub 下载,或复制粘贴后保存为 news_piece.txt。

我们可以使用 pathlib 库读取文件内容:

from pathlib import Path

file = Path("news_piece.txt")
text = file.read_text()

随后,将文档拆分为若干分块,因为 RAG 系统在文本被切分后效果更佳。在本例中,我们将文本按每 512 个字符拆分:

chunk_size = 512
chunks = [text[i : i + chunk_size] for i in range(0, len(text), chunk_size)]

len(chunks)
4

然后,使用上一节的 get_text_embedding 函数为每个分块生成嵌入:

text_embeddings = np.array([get_text_embedding(chunk, client) for chunk in chunks])

接下来,通常会将嵌入存入向量数据库,以便高效处理与检索。向量数据库有很多选择。我们使用 faiss——一个用于相似度搜索的开源数据库。

import faiss  # pip install faiss

d = text_embeddings.shape[1]
index = faiss.IndexFlatL2(d)

index.add(text_embeddings)

index 是一个 Index 类的实例,定义了数据库的结构。d 是嵌入空间的维度。

调用 add 方法会将文档中的信息加入向量数据库,随后我们就可以基于这些内容提出问题了。但在此之前,我们需要将提出的问题也转换为嵌入:

import numpy as np

questions = [
   "How much is Microsoft going to spend for its new data center?",
   "When did FTX collapse?",
]

question_embeddings = np.array([get_text_embedding(q, client) for q in questions])

接着,将 question_embeddings 数组传入 Index 对象的 search 方法:

D, I = index.search(question_embeddings, k=4)  # distance, index

retrieved_chunk = [chunks[i] for i in I.tolist()[0]]

search 方法会返回最可能包含答案的向量(基于相似度搜索):

len(retrieved_chunk)
4
print(retrieved_chunk[2])
ay defrauded investors in full and provide the vast majority with interest. The failed cryptocurrency exchange platform filed its proposal late Tuesday to a federal bankruptcy court for approval.

Since FTX collapsed in 2022, CEO John Ray III (see previous write-up) has worked to track down more than $8B in missing assets to repay an estimated $11.2B owed to creditors. This week, Ray said the company has recovered between $14.5B and $16.3B, with much of the funds tied to government-seized FTX properties or

现在,我们可以将这些文本作为上下文传给 Mixtral 8X22B,并据此提问。先构建提示词:

prompt = f"""
Context information is below.
---------------------
{retrieved_chunk}
---------------------
Given the context information and not prior knowledge, answer the query.
Query: {questions}
Answer:
"""

现在,通过 client 将其传给模型:

chat_response = client.chat(
   model=model,  # Mixtral 8x22B
   messages=[ChatMessage(role="user", content=prompt)],
)

print(chat_response.choices[0].message.content)
Microsoft will spend $3 billion for its new data center in Racine, Wisconsin. FTX collapsed in 2022.

答案是正确的!

我们构建了一个非常基础的 RAG 流水线。实际中,RAG 流水线非常强大——能处理多种输入(文本、图像、音频、视频),并可在大规模场景下运行,而不仅限于我们这种单文件的小示例。

如果您想学习如何构建更强大的 RAG 流水线,欢迎阅读我们的《如何使用 LangChain 构建 LLM 应用》教程。

函数调用

Mixtral 8X22B 的原生能力之一是函数调用。在 LLM 语境中,函数调用是一种技术,使 LLM 能够以触发特定函数执行的方式理解并响应提示。其含义如下:

  • 标准 LLM 响应:LLM 基于训练数据为提示生成文本,通常不可预测且缺乏结构。
  • 使用 Mixtral 的函数调用:通过函数调用,Mixtral 8X22B 可以根据提示类型调用预定义的自定义函数,以结构化其输出。Mixtral 通常以可预先定义的 JSON 结构返回结果,使响应更可预测、更有结构。

演示函数调用的细节超出本文范围。不过,您可以查看Mistral AI 文档的此页了解其具体用法。

结语

本文介绍了 Mistral AI 于 2024 年 4 月发布的 Mixtral 8X22B 模型。凭借架构优势,它已成为领先的开源 LLM 之一,并在诸多基准测试中击败了 Llama 2、Command R+ 等热门模型。

除架构细节外,我们还学习了如何在若干实用场景中使用该模型,如文本生成、同义改写检测以及构建 RAG 流水线。若您想进一步释放 Mixtral 8X22B 的潜力,可参考以下资源:

Bexruz (Bex) Tuychiev

作者

Bexruz (Bex) Tuychiev

我是一名数据科学内容创作者,拥有超过 2 年的经验,并在 Medium 上拥有较大的读者群。我喜欢用略带讽刺的笔调撰写有关 AI 和机器学习的深度文章——毕竟总得想点办法让这些内容不那么枯燥。我已发表 130 多篇文章,并制作了一门 DataCamp 课程,另有一门正在筹备中。我的内容已被超过 500 万人次阅读,其中有 2 万人在 Medium 和 LinkedIn 上成为关注者。 

主题