跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • 浅色
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • 深色
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(LCZ-Blue)
  • 不使用皮肤
  • LCZ-Green
  • LCZ-Blue
  • LCZ-Black
折叠
品牌标识

抡锤者

首页 版块 标签
硬件
装备秀
AI 广场 App
  1. 主页
  2. 版块
  3. AI硬件
  4. 把 256GB M5 Ultra 调到甜点区:mlx-serve 设置优化与 200 发上下文实测

把 256GB M5 Ultra 调到甜点区:mlx-serve 设置优化与 200 发上下文实测

已定时 已固定 已锁定 已移动 AI硬件
apple-m5mac本地模型
1 帖子 1 发布者 58 浏览 1 关注中
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • cc tgoC
    cc tgoC
    cc tgo
    贵族大夫
    编写于 最后由 编辑
    #1

    把 256GB M5 Ultra 调到甜点区:mlx-serve 设置优化与 200 发上下文实测

    一台 Mac Studio(M5 Ultra / 256GB)跑本地大模型做长上下文开发负载,能到什么水平?
    我用约 200 发合成基准把答案给到你:8 路并发、131K 上下文、热缓存每步 1.1–1.9 秒、零崩溃——并拿 11 天里 10,025 次真实模型调用做了对账验证。
    本文给出完整设置(可参考自测)、全部实测数据、生产数据对账、外部权威榜单对照,以及复现方法。


    一、测试环境

    项目 配置
    机器 Mac Studio
    芯片 Apple M5 Ultra(CPU 36 核:12 超级 + 24 性能;GPU 80 核)
    内存 256 GB 统一内存(可用带宽约 1.2 TB/s)
    存储 2 TB
    系统 macOS 27.2(Metal 4)
    推理服务 mlx-serve 26.11.2(MLX Core 托管,OpenAI 兼容 API)
    主力模型 Qwen3.8-Flash-Next,iQ-MLX 4.7bpw 量化(约 125B 总参 / 每 token 约 6B 激活)

    说明:全部测试使用合成数据(构造长文档 + 埋点探针),不涉任何真实内容;温度、深度、题型、样本数在下文逐项标注。


    二、设置:抄作业区

    mlx-serve(MLX Core 应用)内共动了 6 项设置。改前 / 改后对照:

    设置项 改前(默认) 改后 为什么
    最大并发 1 8 并发 1 时批量任务纯排队;8 路吃满批处理窗口(见第四节数据)
    前缀缓存 2 GB 32 GB 多轮 agent 负载每步只算新增 token,32GB 下实测 121K–186K 缓存命中、零逐出
    同时加载模型数 3 1 多模型驻留互相挤内存;单模型专职服务
    ANE 图像/音频加速 开 关 纯文本负载用不到,关掉释放约 60GB 内存占用
    最大上下文 256K 192K 关键项,见下方"崩溃根因"
    监听地址 0.0.0.0 127.0.0.1 本机自用,不暴露局域网

    崩溃根因:内存账面超卖

    改前的组合(256K 上下文 × 3 模型驻留 × 高并发)在账面上允许约 270GB 超过 256GB 物理内存的分配。实测后果:200K 级长上下文负载直接打崩服务(进程自愈重启)。

    改后 192K 成为硬边界:越界请求明确返回 400 错误,不再崩溃。压力测试佐证:32 路并发 × 131K 上下文复测,零失败。

    一句话结论:"能配多大上下文"和"该配多大上下文"是两回事。配置容量要以内存账面为准,而不是模型标称上限。


    三、单请求速率

    单请求、温度 0、冷缓存(每发全新前缀,杜绝缓存命中),105K–200K 上下文区间:

    上下文深度 prefill 平均速率 decode 平均速率
    105K 3,952 tok/s 172.7 tok/s
    131K 5,030 tok/s 152.5 tok/s
    160K 4,935 tok/s 147.7 tok/s
    200K 4,851 tok/s 143.3 tok/s
    • prefill 约 5K tok/s 且随深度平坦——它是算力项,长上下文不衰减。
    • decode 约 143–173 tok/s——它是带宽项,贴着 1.2TB/s 内存带宽的顶,深度增加只有轻微下滑。
    • 短上下文(50K/80K)样本受冷启动影响明显偏低,不列入上表(诚实口径)。

    热缓存:多轮对话的真正体验来源

    多轮负载(每步新增约 4K token)下,前缀缓存命中后每步只计算新增部分:

    场景 冷启动首步 热步 TTFT 样本
    单会话,131K 深度 23.1 s 15/16 步落在 1.1 – 1.9 s(紧随冷启动的 1 步为 23.8 s) 16 缓存命中步
    双会话并发,100K 深度 42.8 s 均值 3.4 s 29 步

    实测缓存命中量 121K–191K token,32GB 缓存下零逐出。这就是"长任务每步一两秒"的全部秘密:不是模型变快了,是每步只算 4K 新 token。


    四、并发账:8 路是甜点

    131K 上下文、每请求输出约 70 token、每路独立填充前缀(杜绝并发路之间缓存互蹭)、温度 0:

    并发 整轮墙钟 摊到每请求 端到端产能 平均首 token 延迟
    单线基线 44.8 s 44.8 s 0.022 req/s —
    2 67.9 s 34.0 s 0.029 req/s 44.9 s
    4 121.7 s 30.4 s 0.033 req/s 76.7 s
    8 190.4 s 23.8 s 0.042 req/s 94.8 s
    16 445.0 s 27.8 s 0.036 req/s 238.5 s
    32 885.6 s 27.7 s 0.036 req/s 457.2 s

    三个硬结论:

    1. 8 路是拐点:每请求 23.8s,约为单线(44.8s)的一半;端到端产能 0.042 req/s 为全场最高。
    2. 超过 8 路反而下降:16/32 路端到端产能跌回 0.036 req/s,排队成本开始吃掉批处理收益。
    3. prefill 串行是硬顶:131K 一发 prefill 约 26 秒,16 路和 32 路的整轮墙钟几乎线性翻倍——批处理救不了 prefill 排队。

    180K 深度下 8 路整轮 266.1s(每请求 33.3s,0.030 req/s)——深度越高,prefill 硬顶越明显。

    口径提醒:并发收益只认端到端(墙钟 ÷ 请求数)。decode 窗口的瞬时总吞吐会被排队结构放大,拿它宣传"32 路千余 tok/s"没有意义——用户等的是整轮墙钟。


    五、质量实测:哪里满配,哪里塌方

    检索类(5 题型 × 多深度 × 多并发,温度 0)

    题型:语义检索 / 变量追踪 / 调用链追踪 / 跨文档聚合 / 首中尾位置探针。

    深度 结果
    131K(含 2/4/8/16/32 路并发轮) 62/62 全对,无 lost-in-the-middle
    180K 4 类题型 14/14,但跨文档聚合题 1/14 塌方

    代码类(4 题型 × 50K–200K,温度 0,共 38 发)

    题型 50K 105K 131K 200K 合计
    代码埋点检索 6/6 10/11 7/11 6/10 29/38
    多步算术链 2/6 0/11 3/11 2/10 7/38
    代码编辑 3/6 3/11 3/11 1/10 10/38
    跨文件引用 6/6 2/11 7/11 6/10 21/38

    两个诚实的发现:

    • 多步算术链与代码编辑是该模型的稳定短板,50K 短上下文就挂——这不是长上下文问题,是模型能力问题。对策:重要计算一律交给代码执行,不要让模型口算。
    • 跨文件引用从 50K 的 6/6 掉到 105K 的 2/11——这类题对深度敏感。

    采样稳定性(温度 0.7 × 5 遍 × 三水位)

    105K / 131K / 160K 三个深度的得分均值分别为 0.55 / 0.60 / 0.55,持平:输出抖动与上下文深度无关。深度不增加随机性,只改变命中率。


    六、生产数据对账:10,025 次真实调用的上下文洞察

    合成基准之外,我把这台机器 11 天里 52 个会话、10,025 次真实模型调用的 usage 记录全部提取做了对账(只取 token 计数与时间戳字段,零文本内容)。合成实验说"应该如此",生产数据说"确实如此"——这一节是全文最有说服力的部分。

    真实负载长什么样

    10,025 次调用的上下文深度(输入 + 缓存读取)分布:

    深度区间 占比
    0–32K 4.5%
    32–64K 19.2%
    64–100K 34.4%
    100–131K 34.2%
    131–160K 3.0%
    >160K 4.7%
    • 深度中位数 92.6K、P90 129.2K——超过 4 成的真实调用跑在 100K 以上。本地 agent 负载不是"偶尔长文",而是长期贴着窗口上限运行。
    • 单会话最长跨度 91.5 小时、256 次调用、峰值深度 261K(旧设置期)——长时任务的深度是单调爬升的:实测某会话轨迹 24K → 68K → 101K → 134K → 197K → 258K,中途不回头。

    缓存命中率的两级分化(关键洞察)

    口径 命中率
    全部调用平均 46.0%
    深度 ≥100K 的调用 均值 95.1%,中位 99.7%
    深度 ≥100K 且命中率 ≥95% 的样本占比 94.3%

    全局 46% 看着寒酸,真相是:浅调用(会话开头、压缩后首步)拉低了平均,深调用几乎全命中。深调用 95.1% 的实测命中率,与合成基准热缓存实验的 94% 命中互相印证——第三节"每步只算新增 token"的机制,在生产环境原样成立。这也解释了为什么前缀缓存从 2GB 加到 32GB 是本次调优收益最大的一项:真实负载就是 121K–191K 的缓存体量。

    压缩行为实测

    11 天里共 50 次上下文压缩(深度骤降 >40% 判定),压缩前深度中位数 130,880——即会话实际是爬到约 131K 满窗附近才被压缩回收,76% 的压缩事件落在 100–135K 区间。压缩后深度回落、缓存重建、继续爬升,循环往复。这验证了"131K 窗口 + 自动压缩"作为长时任务的续航机制在生产中稳定工作。

    设置收敛的前后对照(生产侧证据)

    指标 旧设置期(10-29 起) 新设置期(11-08 晚起)
    调用数 9,758 267
    深度 >160K 占比(质量塌方区) 4.81% 0%
    深度 131–160K 占比 2.77% 11.52%
    观测到的最大深度 261,626 150,311

    旧设置(256K 窗口)放任了近 5% 的调用跑进第五节实测的"质量塌方区"(>160K,聚合类任务开始丢分);新设置把深度压回满配区内,131–160K 占比上升说明负载被引导到窗口上限而非放任越界。样本量提示:新设置期仅 267 次调用(约 1 天),此对照为初步证据,持续观察中。


    七、外部权威数据对照

    同机型(M5 Ultra 256GB)公开榜单,供横向参考:

    mlx-serve 官方基准(benchmarks.md,llmprobe 测法:预热丢弃、3 次取中位、代码补全 prompt、投机解码标注在旁):

    模型 26.11.2 decode
    Qwen3.6 35B-A3B 4b(MTP) 439 tok/s
    Qwen3.8 27B 4b(dflash) 243 tok/s
    Gemma 4 E4B 4b(pld) 199 tok/s
    Gemma 4 26B-A4B 4b(pld) 189 tok/s
    Qwen3.8 Flash-Next iQ-MLX 4.7bpw(mtp) 168 tok/s

    来源:ddalcu/mlx-serve benchmarks.md;官方 README 另载 v26.11.1 同机 Flash-Next 4.7bit 为 180 tok/s(README)。

    第三方栈参考(llama.cpp,非同引擎,仅作量级对照):Qwen3.8 27B 空上下文 46.3 tok/s、128K 上下文 30.1 tok/s(getneotiler 实测);社区汇编给 Flash-Next 长上下文 60–85 tok/s 区间(presenc 汇编,转引 Context Studios)。

    本文自测 vs 官方榜单:本文单线 decode 143–173 tok/s(105K–200K、无投机解码、长上下文),与官方 168 tok/s(短 prompt + MTP 投机解码)同量级、口径可解释——长上下文吃带宽,投机解码提短 prompt 表现。


    八、使用场景建议

    你的场景 建议 预期体验
    交互式编码 / 多轮对话 单线 + 热缓存,上下文控制在 131K 内 首步冷启动约 20–40s,之后每步 1–2s
    批量离线任务(摘要、改写、数据生成) 并发开 8,别贪多 每请求约 24s(131K),产能 0.042 req/s
    超长文档(>180K) 避免;必须时拆分 180K 起聚合类任务不可靠
    精确计算 / 数值推理 任何深度都别信模型口算 生成代码执行,模型只写代码
    多模型混跑 关到单模型专职 多驻留 = 内存超卖 = 崩溃风险

    上下文窗口设置建议 131K(如果客户端可配):质量满配区之内、距 192K 服务硬限有安全余量、压缩触发线(约 0.8×)也落在满配区内。三重约束,131K 是综合最优解——第六节的生产数据佐证了这一点:真实负载 4 成跑在 100K+,压缩事件中位触发深度 130,880,正好贴着这个窗口。


    九、复现方法与测量教训

    想在自己机器上复跑,方法如下(判据先于数据):

    1. 合成埋点:程序生成长文档,按 token 深度均匀埋入探针(数字对、变量名、代码片段),题面与校验点同源生成。
    2. 五题型:语义检索 / 变量追踪 / 调用链 / 跨文档聚合 / 首中尾位置——位置探针专打 lost-in-the-middle。
    3. 温度纪律:质量测温度 0(确定性,重跑零方差);稳定性测必须温度 >0,否则测不到抖动。
    4. 并发防污染:每路并发用不同随机种子独立填充前缀,否则后发路蹭前发路的缓存,数据全废。
    5. 判分器先单测:判分 bug 会把满分判成零分(我们踩过空格匹配和变量名漂移各一轮)。
    6. 吞吐只认端到端:墙钟 ÷ 请求数;decode 窗口瞬时和会被排队结构放大。
    7. macOS 采样小坑:BSD awk 没有 strftime,内存采样脚本用 Python 写。
    8. 生产对账口径(第六节):从 agent 会话日志的 usage 字段提取 inputTokens / cacheReadTokens / outputTokens 与时间戳;命中率 = cacheRead ÷ (input + cacheRead);压缩事件判定 = 相邻调用间隔 <10 分钟内深度骤降 >40%(间隔阈值排除"重启恢复首调"的假压缩——实测 52 个候选里 2 个是恢复、50 个是真压缩)。全程零文本读取。

    数据窗口与免责

    • 实测窗口:合成基准 2026-11-08,mlx-serve 26.11.2,macOS 27.2,全部数据可在评论区按上述方法复现核对;生产对账窗口 2026-10-29 至 11-09(52 会话 / 10,025 次调用),仅提取 token 计数与时间戳,不含任何会话文本。
    • 样本量说明:合成基准约 200 发/配置组合,低于学术基准(如 RULER 的 1000 题/配置)口径,关键结论均经多轮交叉验证;个别短上下文样本受冷启动影响已剔除并注明。生产对账中新旧设置对照的新期样本仅约 1 天(267 次),标注为初步证据。
    • 换模型、换量化档、换 mlx-serve 大版本后,本文数字会失效,需重跑。

    *欢迎交流设置与复现结果。希望能帮到大家,肝测试挺费人费机器。

    1 条回复 最后回复
    0

    你好!看起来您对这段对话很感兴趣,但您还没有一个账号。

    厌倦了每次访问都刷到同样的帖子?您注册账号后,您下次访问时都将自动回到上次浏览的位置,并可选择接收新回复的通知(通过电子邮件或推送通知)。您还可以收藏帖子、为帖子点赞,以此向其他社区成员表达您的感谢。

    有了你的建议,这篇帖子会更精彩哦 💗

    注册 登录
    回复
    • 在新帖中回复
    登录后回复
    • 从旧到新
    • 从新到旧
    • 最多赞同


    • 登录

    • 登录或注册以进行搜索。
    • 第一个帖子
      最后一个帖子
    0
    • 版块
    • 最新
    • 标签
    • 热门
    • 用户
    • 群组