LM Studio 中统一多模态 MLX 引擎架构的介绍

LM Studio 的 MLX 引擎 (MIT) 利用了两个强大的 Python 包,用于在 Apple Silicon M 芯片上高效运行 LLM:mlx-lm 用于文本生成(由 @awni、@angeloskath、Apple 开发)和 mlx-vlm 用于支持视觉的语言模型(由 @Blaizzy 开发)。
从 mlx-engine 提交 f98317e(应用内引擎 v0.17.0 及更高版本)开始,我们迁移到了一个新的统一架构,该架构将这些包的底层组件融合在一起。现在,mlx-lm 的文本模型实现始终被使用,而 mlx-vlm 的视觉模型实现则以“附加组件”的形式模块化使用,以生成可被文本模型理解的图像嵌入。

新的 mlx-engine 统一视觉模型架构。mlx-lm 文本模型通过 mlx-vlm 视觉附加组件进行扩展
这极大地提高了使用多模态 MLX VLM(例如 Google 的 Gemma 3)时的性能和用户体验。例如,与 VLM 进行纯文本聊天现在可以受益于提示缓存——以前仅限于纯文本 LLM 的功能——从而显着加快后续响应速度。这使得 MLX VLM 可以与纯文本 LLM 无缝互换用于文本任务,同时提供视觉功能作为额外优势。
👓 继续阅读,深入了解问题、解决方案以及我们如何在 LM Studio 的 MLX 引擎中实现这一统一架构。
多模态 LLM 是一种可以接受多种模态输入的 LLM。这意味着除了能够处理文本输入之外,LLM 还可以接受图像和/或音频输入。
新的 MLX 引擎尚不支持音频,但我们计划这种方法也适用于音频输入。
通常,具备视觉能力的 LLM 通过以下流程摄取图像输入

多模态视觉 LLM 的一般操作流程:将图像转换为可被文本模型理解的嵌入,使用文本模型生成输出
"这是什么?" → [0.83, 0.40, 0.67, ...]image.png → [0.28, 0.11, 0.96, ...][0.83, 0.40, 0.67, ...] + [0.28, 0.11, 0.96, ...] → [0.83, 0.40, 0.67, ..., 0.28, 0.11, 0.96, ...]如果提示中没有图像,则“合并后的嵌入”仅仅是文本嵌入。
在 MLX Python 生态系统中,有两个主要的库提供模型实现和与 Apple Silicon 上的 LLM 交互的基础设施
历史上,mlx-lm 包含了没有多模态功能的纯文本模型实现,而 mlx-vlm 则是 MLX VLM 实现的实际归宿。

mlx-lm 和 mlx-vlm 中的模型实现组件。黄色 = 文本模型组件。蓝色 = 视觉模型组件
LM Studio 的 mlx-engine 最初是使用简单的“分叉”架构开发的,以支持纯文本模型和具备视觉功能的模型

旧 mlx-engine 的分叉视觉模型架构。黄色 = 文本模型组件。蓝色 = 视觉模型组件
如果模型具备视觉功能,则将专门使用 mlx-vlm 模型实现(文本 + 视觉)。如果模型是纯文本,则将专门使用 mlx-lm 模型实现(文本)。
在每个路径中都使用了一个独特的(不同的)文本模型实现(来自 mlx-lm 或来自 mlx-vlm)。
mlx-engine 的简单分叉架构存在以下问题
mlx-lm 和 mlx-vlm 的功能不完全一致或行为存在细微差异时,我们应该使用哪个?mlx-lm 还是 mlx-vlm?我们是否应该根据请求在两者之间热切换加载(复杂)?
同一个文本模型存在两个独立的版本
我们寻求将 mlx-lm 和 mlx-vlm 的核心组件结合起来,为所有 MLX LLM 和 VLM 创建一个“统一”(无分叉)推理引擎。
在与 @awni 和 @Blaizzy 进行宝贵的讨论后,我们通过以下贡献实现了这一点
mlx-lmmlx-vlm
新的 mlx-engine 统一视觉模型架构。mlx-lm 文本模型通过 mlx-vlm 视觉附加组件进行扩展
在这个统一架构中,始终从 mlx-lm (2) 加载多模态 LLM 的核心文本模型,不再可能从 mlx-vlm 加载略有不同的文本模型。
然后我们有条件地加载一个 VisionAddOn,它使用 mlx-vlm 功能 (3,4) 从图像生成可被 mlx-lm 文本模型理解的嵌入(参见 mlx-engine 中的 Gemma3VisionAddOn 实现)。
通过这种设置,我们能够以流线型和单一路径的方式推断多模态模型。这有助于我们发布更清晰、更易维护的 LM Studio MLX 引擎,并提高性能。
Gemma 3 12B QAT,均在 M3 MacBook Pro 上使用 MLX 4 位。统一架构使后续 TTFT 速度提高约 25 倍
mlx-engine 中的 VisionAddOnsLM Studio 新 mlx-engine 统一架构的要点在于,它允许我们对所有多模态模型使用 mlx-lm 的文本模型实现,同时仍然能够利用 mlx-vlm 的视觉模型组件来生成可被文本模型理解的图像嵌入。
这是通过引入 VisionAddOns(源代码)实现的,它们是模块化组件,可用于为多模态模型生成图像嵌入。这些 VisionAddOns 实现了一个由 BaseVisionAddOn 抽象类定义的通用接口,例如
class BaseVisionAddOn: """ Base class that defines the interface for a VisionAddOn. """ @abstractmethod def __init__(self): """ Where load of vision model components is intended to occur. """ @abstractmethod def compute_embeddings( self, text_model: nn.Module, prompt_tokens: mx.array, images_b64: List[str], ) → mx.array: """ Returns input embeddings for the language model after text/image merging of the prompt """
VisionAddOns 生成图像嵌入,这些嵌入可以作为 mlx-lm 的 stream_generate() 函数的新 input_embeddings 参数的输入(参见对 mlx-lm 的提交)。
目前,Gemma 3(Gemma3VisionAddOn)和 Pixtral(PixtralVisionAddOn)是唯二已迁移到统一架构的模型。然而,该架构的设计使得可以轻松将更多 VisionAddOns 添加到 mlx-engine 的 vision_add_ons 目录,然后连接到 ModelKit 此处
VISION_ADD_ON_MAP = { "gemma3": Gemma3VisionAddOn, "pixtral": PixtralVisionAddOn, }
我们非常欢迎向我们的开源仓库 https://github.com/lmstudio-ai/mlx-engine 贡献以扩展此模式!例如,请参阅 mlx-engine 问题 将 VisionAddOn 模式扩展到 Qwen2.5VL #167。
mlx-engine 仓库:https://github.com/lmstudio-ai/mlx-engine,查看并/或贡献代码。