Mistral AI 再次掀起了一场革命它是最新的语言型号,不仅提高了标准,还重新定义了标准。Mistral AI 隆重推出的开放式重量级产品,在人类基准测试中的表现超过了 GPT-3.5 Turbo、Claude-2.1、Gemini Pro 和 Llama 2 70B 等著名模型。令人兴奋的是,基本模型和指导模型 Mixtral 8x7B - Instruct 都可以在 Apache 2.0 许可下进行探索!
什么是 MoE?
Mistral 7x8B 采用路由器将 8 个专家中的 2 个分配给每个令牌,提供高达 470 亿个参数。尽管在推理过程中只主动使用了 130 亿个参数,但 Mixtral 8x7B 在大多数基准测试中都超过了 70B 的 Llama 2,推理速度提高了六倍,令人印象深刻。
这项巧妙的技术在提高模型参数的同时,还控制了成本和延迟,每个令牌只使用了全部参数集的一小部分。Mixtral 使用多语言数据对 32k 标记上下文进行了预训练,并在Transformer 架构的基础上进行了关键修改,包括完全支持密集上下文,以及用 Mixture-of-Expert 层取代前馈块。
简而言之,可以把它想象成 Mistral 7B 的同胞兄弟,但又有所变化--每层包含 8 个专门的前馈块。
论文介绍了 Mistral(7B/8x7B)与 Llama 2(7B/13B/70B)在各种基准(包括 MMLU、常识推理、世界知识、阅读理解、数学和代码)上的性能比较,得出了令人信服的结论。值得注意的是,在大多数基准测试中,Mixtral 都明显优于 Llama 2 70B,在主动参数减少 5 倍的情况下取得了显著优势。虽然 Mixtral 在阅读理解基准测试中的表现不相上下,但它在代码和数学领域的表现尤为突出,大大超过了 Llama 2 70B。这凸显了 Mixtral 在以最佳资源利用率提供更高性能方面的优势。
代码执行
乍一看,从 8 个专家中为每个标记分配 2 个专家的概念似乎令人费解,但深入研究代码的实现,就会发现其中的复杂性,并揭示出一个非常简单的过程。
首先,我们建立了一个虚无的前馈层,其特点是输入和输出保持相同形状的瓶颈结构。这一层作为基础元素,随后将在专家混合物(MoE)架构中重新使用,并增加复制。
class FeedForward(nn.Module):
def __init__(self, args: ModelArgs):
super().__init__()
self.w1 = nn.Linear(args.dim, args.hidden_dim, bias=False)
self.w2 = nn.Linear(args.hidden_dim, args.dim, bias=False)
self.w3 = nn.Linear(args.dim, args.hidden_dim, bias=False)
def forward(self, x) -> torch.Tensor:
return self.w2(nn.functional.silu(self.w1(x)) * self.w3(x))
接下来,包含维数(batch、sequence_length、hidden_dimension)的张量被送入前馈层,通过瓶颈结构产生类似大小的输出。
# vanila implementation without MoE
class TransformerBlock(nn.Module):
def __init__(self, args: ModelArgs):
# ...
self.feed_forward = FeedForward(args=args)
# ...
在 MoE 的实现中,前馈层仍被使用,但在一个名为 MoeLayer 的模块中被复制了数个专家层。该模块由一组专家层(前馈层)和一个作为门的线性层组成,在根据门对数选择最高专家数方面至关重要。
class MoeLayer(nn.Module):
def __init__(self, experts, gate, moe_args):
super().__init__()
assert len(experts) > 0
# list of feedforward layers
self.experts = nn.ModuleList(experts)
# list of linear layers
self.gate = gate
self.args = moe_args
def forward(self, inputs: torch.Tensor):
# (m, seq_len, dim) --> (m * seq_len, dim)
inputs_squashed = inputs.view(-1, inputs.shape[-1])
# (m * seq_len, num_experts)
gate_logits = self.gate(inputs_squashed)
# (m * seq_len, num_experts_per_tok),
weights, selected_experts = torch.topk(
gate_logits, self.args.num_experts_per_tok)
weights = nn.functional.softmax(
weights, dim=1, dtype=torch.float).type_as(inputs)
# (m * seq_len, dim)
results = torch.zeros_like(inputs_squashed)
for i, expert in enumerate(self.experts):
# index of batch and expert
batch_idx, nth_expert = torch.where(selected_experts == i)
# weightage * output of expert layers (selected_m, num_expert)
results[batch_idx] += ( weights[batch_idx, nth_expert, None] *
expert(inputs_squashed[batch_idx]) )
# (m * seq_len, dim) --> (m, seq_len, dim)
return results.view_as(inputs)
该forward方法采用输入张量 ( inputs) 并执行以下步骤:
从本质上讲,Mixtral 的创新方法在于将稀疏的专家混合网络无缝集成到Transformer 架构中,在保持代码结构的可理解性和高效性的同时,释放出先进的功能。
class TransformerBlock(nn.Module):
def __init__(self, args: ModelArgs)
# ...
self.feed_forward = MoeLayer(
experts=[FeedForward(args=args) for _ in range(args.num_experts)],
gate=nn.Linear(args.dim, args.num_experts, bias=False),
moe_args=args.moe,
)
# ...
结论
揭开让大型语言模型(LLM)更高效的秘密一直是一个巨大的挑战,而答案可能就在专家混合物(MoE)模型的创新世界中。
改变游戏规则的 Mixtral 8x7B 已成为这一领域的先驱,不仅在开源模型中实现了最先进的性能,还重新定义了大规模语言处理的格局。Mixtral 的与众不同之处在于,它在每个时间步中只战略性地使用了两个专家,每个标记只有 13B 活动参数,展现了前所未有的效率。令人兴奋的是,Mixtral 8x7B Instruct 在人类评估基准中处于领先地位,超过了 Claude-2.1、Gemini Pro 和 GPT-3.5 Turbo 等著名模型。