返回首页

Mac 上 Qwen 3.5 的 LLM 服务器基准测试 — 2026 结果

比较八个用于在 MacBook Pro M2 Max 上运行 Qwen 3.5 35B MoE 的本地 LLM 服务器。单用户和多用户场景下的性能分析。为开发者选择框架的关键推荐。

Mac 上的 Qwen 3.5:2026 年哪个 LLM 服务器更快?
Advertisement 728x90

## Mac 上针对 Qwen 3.5 的 8 个本地 LLM 服务器基准测试:2026 年惊人结果

在配备 M2 Max 的 MacBook Pro 上,对八个本地 LLM 服务器运行 Qwen 3.5 35B MoE 进行了详细基准测试。单用户情况下,速度差异仅为 2%,但两个并行请求时,一个框架实现了 2.17 倍加速,而另一个降至 0.85 倍。分析揭示了连续批处理、虚假速度指标以及内存管理问题的关键细微之处。

为什么要在本地运行 LLM:三大技术原因

对于开发者和工程师来说,本地运行模型能解决三大关键挑战:

  • 数据隐私。 处理合同、规格说明和客户聊天记录,而无需发送到云端 API。本地模型能实时匿名化个人信息(姓名、凭证)。
  • 自主编码代理。 OpenCode 和 Aider 等工具需要 OpenAI 兼容的端点。设置 base_url: http://mac.local:8000/v1 即可运行代理,无需遥测或速率限制,从而节省云端令牌费用。
  • 无网络延迟。 M2 Max 上 4 位量化 35B 模型生成响应速度快于云端 API,因为零往返时间。在 64GB 统一内存下,模型占用约 20GB,还留有 KV cache 空间。

这些因素使 Mac 本地服务器成为专业用途的可行替代方案,尤其适用于敏感数据场景。

Google AdInline article slot

为什么在 Apple Silicon 上 MLX 优于 llama.cpp

选择 MLX 而非 llama.cpp 是基于 Apple Silicon 架构:

  • 统一内存。 M 系列芯片上,CPU 和 GPU 共享单一内存池。35B 模型占用 20GB,无需在 RAM 和 VRAM 间复制(不同于 NVIDIA)。
  • 性能。 MLX 通过原生 Metal 编译,比 llama.cpp 快 10-30%。M2 Max 提供约 400 GB/s 内存带宽,实现实时 50-80 tokens/sec。
  • 原生连续批处理。 MLX 生态系统开箱即支持并行请求处理,而 llama.cpp 需要额外配置。

重要提示:Metal 不支持进程间 GPU 上下文共享。所有测试均使用单一服务器,避免资源冲突。

对比框架:选择标准

基准测试涵盖 MLX 生态系统的六个服务器(两个因与 Qwen 3.5 35B MoE 不兼容而排除):

Google AdInline article slot
  • mlx-openai-server (Python 3.11) — 支持连续批处理、多模型 YAML 配置、结构化输出。
  • mlx-omni-server (Python 3.11+) — 双 API (OpenAI + Anthropic)、TTS/STT。
  • Rapid-MLX (Python 3.10+) — 易部署、1900+ 测试、Cursor/Aider 集成。
  • vllm-mlx (Python 3.10+) — 分页 KV cache、多模态,但存在关键 SSE 解析器 bug。
  • omlx (Python) — 分层 KV cache (RAM + SSD)、Web 仪表板,但硬性 32768 token 限制。
  • mlx-vlm (Python 3.10+) — 支持 40+ 架构,但长提示下性能病态下降。

排除项:

  • higgs (Rust) — 不支持 qwen3_5_moe
  • mlx-serve (Zig) — 需要 macOS 15 (Sequoia)。

关键选择标准:原生支持 MLX 格式的 Qwen 3.5 35B MoE,无需转换。

基准测试方法:性能测量方式

测试在 16 英寸 MacBook Pro M2 Max (64GB 统一内存) 上运行,使用 mlx-community/Qwen3.5-35B-A3B-4bit。Python 基准测试框架包括:

Google AdInline article slot
  • 加载场景:

* run_single — 顺序处理 8 个提示(100 到 53000 tokens)。

* run_double_batch — 通过 asyncio 屏障实现两个并行请求:

gate = asyncio.Event()
task_a = create_task(chat_stream(..., start_gate=gate))
task_b = create_task(chat_stream(..., start_gate=gate))
await asyncio.sleep(0.05)
gate.set()
res_a, res_b = await gather(task_a, task_b)
  • 指标:

* wall_tps_p50 — 挂钟时间中位数 tokens/sec(主要指标)。

* ttft_p50 — 首 token 时间 (TTFT)。

* speedup — 批处理效率(两个请求 vs. 一个请求的 wall_tps 比率)。

使用中位数而非均值,以避免提示长度变异导致的异常值。每项测试重复 5 次。

结果:单用户 vs. 并行处理

单用户性能在各服务器间相似(差异在 2% 内)。两个并行请求时差距显现:

  • mlx-openai-server 实现 2.17× 加速 — 唯一有效连续批处理的框架。
  • vllm-mlx 显示虚假 14000 tokens/sec,因 SSE 解析错误导致 gen_tps 偏差。
  • Rapid-MLX 缺少流式生成,因此 TTFT 等于总响应时间。
  • mlx-omni-server--workers 2 时降至 0.85× 加速
  • omlx 对 >32768 tokens 提示返回 HTTP 400。
  • mlx-vlm 因 GC 问题出现循环速度下降(790 → 3.5 tok/s)。

值得注意:某些实现中的二次方注意力复杂度使 52k token 预填充耗时 31 分钟,而非 2-3 分钟。

开发者关键要点

  • 连续批处理对多用户场景至关重要。 仅 mlx-openai-server 在并行请求上实现真正加速。其他框架要么不并行处理,要么需手动调整工作进程。
  • 用真实数据验证指标。 vllm-mlx 的虚假 14000 tok/s 来自 SSE 流处理 bug,导致 gen_tps 不可靠。
  • 统一内存是优势,但非万能。 尽管共享内存池,分层 KV cache(如 omlx)对超长上下文仍很重要。
  • 测试长提示。 mlx-vlm 在 >30k token 提示上的病态下降可能使其无法用于大上下文任务。
  • Python 版本影响稳定性。 Rapid-MLX 经 1900+ 测试最稳健,但批处理速度落后。

— Editorial Team

Advertisement 728x90

继续阅读