头一次发技术贴, 请留情.
本人最近有幸看到了lcz视频并且也开始试着玩hermes. Deepseek很好用但是我一直都有CC和一个打游戏用的5090. 想试试怎么样跑最好. 现在hermes跑在我m1 mac mini 上. DS真的好用很香, 但是抱着爱折腾的心里决定测试一下, 反正有CC帮忙, 很快就部署完成并且测试了下来. 部分由CC替写.
硬件配置
5090 PC
- GPU:RTX 5090 32GB GDDR7
- 推理后端:LM Studio CUDA
- 模型:Qwen 3.6 27B,GGUF Q4_K_M 量化
- 上下文:128K tokens
Mac Studio
- SoC:Apple M4 Max,36GB 统一内存
- 推理后端:LM Studio MLX
- 模型:Qwen 3.6 27B,MLX 4bit 量化
- 上下文:128K tokens
云端
- DeepSeek V4 Flash / V4 Pro(API)
- Claude Opus 4.7 / Sonnet 4.6(通过本地FastAPI代理包装
claude -pCLI 后面会有讲)
Hermes
- Mac mini m1
速度总览
5个不同复杂度的任务,6个模型逐一跑。时间是端到端wall clock。
| 测试场景 | DS Flash | DS Pro | Qwen 5090 | Qwen MLX | Opus 代理 | Sonnet 代理 |
|---|---|---|---|---|---|---|
| 简单问答 | 4.0s | 5.1s | 2.7s | 26.1s | 6.0s | 4.5s |
| 中等代码 | 29.2s | 20.4s | 13.4s | 31.3s | 15.5s | 10.4s |
| 找BUG | 13.2s | 21.0s | 9.0s | 37.9s | 19.6s | 12.3s |
| 逻辑推理 | 9.1s | 15.3s | 10.1s | 32.0s | 10.8s | 16.3s |
| 复杂SQL | 36.4s | 31.3s | 26.5s | 49.2s | 20.4s | 32.4s |
Mac Studio MLX 全场垫底,简单问答都要26秒。后面有详细分析,先看每道题的具体回答。
第1题:简单问答
What is the time complexity of binary search? One sentence.
| 模型 | 时间 | 回答 |
|---|---|---|
| DS Flash | 4.0s | Binary search has a time complexity of O(log n), repeatedly halving the search space with each comparison. |
| DS Pro | 5.1s | O(log n) — each step halves the search space. |
| Qwen 5090 | 2.7s | O(log n) |
| Qwen MLX | 26.1s | O(log n) — each step halves the search space, so it takes logarithmic time relative to the input size. |
| Opus | 6.0s | O(log n) — each comparison halves the search space. |
| Sonnet | 4.5s | O(log n) — each step halves the search space. |
正确性:全员正确,没啥好说的。Qwen 5090 最快最惜字如金,MLX 同一个模型反而写了一句完整的解释——可能是量化差异导致采样路径不同。
第2题:中等代码 — 重试装饰器
Write a Python decorator that retries a function up to N times with exponential backoff on exception. Include type hints.
| 模型 | 时间 | 字符数 | 风格 |
|---|---|---|---|
| DS Flash | 29.2s | 643c | 写了文件,没贴代码,讲解为主 |
| DS Pro | 20.4s | 436c | 写了文件,有on_retry回调 |
| Qwen 5090 | 13.4s | 3160c | 完整代码+示例+edge case |
| Qwen MLX | 31.3s | 2602c | 完整代码,结构跟5090几乎一样 |
| Opus | 15.5s | 1122c | 15行核心代码,ParamSpec完美推导 |
| Sonnet | 10.4s | 1118c | 跟Opus同思路,TypeVar bound |
正确性:
- Opus — 最简洁最正确。15行decorator,
ParamSpec+TypeVar完美保留被装饰函数签名,2**attempt指数退避,没有一行废话。 - Qwen 5090 / MLX — 最全面。logging、jitter防惊群、
functools.wraps、使用示例全有。同一个模型,质量一致。 - Sonnet — 正确但用了
TypeVar bound代替ParamSpec,有个type: ignore不太干净。 - DS Flash / Pro — 正确但都写文件了不贴代码,agent化太重。
第3题:找BUG
merge_sorted 函数缺少处理剩余元素的逻辑。
| 模型 | 时间 | 诊断 |
|---|---|---|
| DS Flash | 13.2s | 发现文件已被修复(上下文污染),额外讨论了稳定性 |
| DS Pro | 21.0s | 正确,解释了slice安全性 |
| Qwen 5090 | 9.0s | 最快,简洁直接 |
| Qwen MLX | 37.9s | 正确,总结很清晰 |
| Opus | 19.6s | 完整修复代码+解释 |
| Sonnet | 12.3s | 附带了具体的输入输出例子 |
正确性:全员正确识别同一个bug(result.extend(a[i:]) + result.extend(b[j:]))。Sonnet的具体例子最直观:merge_sorted([1, 3], [2, 4, 5]) 返回 [1, 2, 3],丢了 4, 5。
第4题:逻辑推理 — 蜗牛爬井
30英尺深井,白天爬3英尺,晚上滑2英尺,第几天到顶?
全员回答:第28天 
| 模型 | 时间 | 风格 |
|---|---|---|
| DS Flash | 9.1s | 表格推演+通用公式+陷阱提醒 |
| DS Pro | 15.3s | 逐步推演+公式 (30-3)/1+1=28 |
| Qwen 5090 | 10.1s | Step-by-step + 陷阱分析 |
| Qwen MLX | 32.0s | 同样的思路,32秒属实慢了 |
| Opus | 10.8s | 5行搞定,极简主义 |
| Sonnet | 16.3s | 数学证明:(n-1)+3≥30 → n≥28 |
正确性:全员正确。经典陷阱是 30÷1=30天,正确答案是前27天净爬27英尺,第28天白天冲刺3英尺直接到顶不用再滑。
第5题:复杂SQL
4张表联查,找回头客(2+完成订单)上季度Top 3品类收入+月环比增长率。
这题拉开差距最大:
| 模型 | 时间 | 字符数 | 亮点 |
|---|---|---|---|
| DS Flash | 36.4s | 2741c | LEFT JOIN pivot思路,附设计决策表 |
| DS Pro | 31.3s | 2750c | RANK()处理并列,附跨DB移植说明 |
| Qwen 5090 | 26.5s | 4107c | 硬编码日期,偏SQLite语法 |
| Qwen MLX | 49.2s | 4837c | 标准PostgreSQL,CROSS JOIN传参 |
| Opus | 20.4s | 2342c | 最快,额外算了avg_mom均值 |
| Sonnet | 32.4s | 2910c | RANK()处理tie,4个key decisions |
正确性排名:
- Opus — 最快+逻辑正确+额外指标。回头客用全局定义(更合理)。
- Sonnet — 最严谨,用RANK()而非LIMIT处理并列。
- Qwen MLX — 虽然最慢但SQL最标准,WINDOW子句规避LAG重复。
- DS Flash — pivot思路有创意。
- DS Pro — 跨数据库移植说明加分。
- Qwen 5090 — 逻辑对但
strftime+ 硬编码日期,不够通用。
有意思的是同一个Qwen模型,5090 GGUF写出了SQLite风格,M4 Max MLX写出了标准PostgreSQL风格——量化方式的微妙差异影响了采样路径。
5090 vs M4 Max MLX:同模型对决
同一个 Qwen 3.6 27B,不同硬件不同量化:
| 测试 | 5090 CUDA | M4 Max MLX | 速度比 |
|---|---|---|---|
| 简单问答 | 2.7s | 26.1s | 9.7x |
| 中等代码 | 13.4s | 31.3s | 2.3x |
| 找BUG | 9.0s | 37.9s | 4.2x |
| 逻辑推理 | 10.1s | 32.0s | 3.2x |
| 复杂SQL | 26.5s | 49.2s | 1.9x |
简单问答差距9.7倍,复杂SQL只差1.9倍。差距随output长度增加而缩小——说明瓶颈不在generation而在prefill。
Prefill性能深度测试
为了验证,做了一组纯prefill压力测试。固定 max_tokens=50(几乎不生成),逐步增大prompt长度:
| Prompt tokens | 5090 CUDA | M4 Max MLX | 速度比 |
|---|---|---|---|
| 119 | 1.1s | 3.3s | 3.1x |
| 1,019 | 1.1s | 7.2s | 6.4x |
| 5,019 | 2.0s | 22.6s | 11.6x |
| 10,019 | 2.5s | 28.7s | 11.7x |
| 20,019 | 4.1s | 63.3s | 15.3x |
几个关键发现:
5090 的 prefill 几乎是平的。 从119 tokens到20019 tokens,只从1.1秒涨到4.1秒——200倍的token量,耗时只增加了3倍。CUDA tensor cores的批量矩阵乘法在这里是碾压级的,大batch prefill几乎是计算bound而非memory bound。
M4 Max MLX 是线性增长。 119 tokens 3.3秒,20019 tokens 63.3秒,基本上每多1000 tokens就多3秒。MLX在Apple Silicon上的prefill实现是memory bandwidth bound的——M4 Max的统一内存带宽大概是546GB/s,看着不低,但跟5090的1.8TB/s GDDR7比差了3倍多,再加上CUDA的tensor core并行度优势,实际prefill吞吐差了10倍+。
这就是为什么Mac Studio跑Hermes这么慢。 Hermes Agent的系统提示词大概有6000-8000 tokens,每次请求Mac Studio光prefill就要20-25秒。5090处理同样的提示词只要2秒。简单问答的26秒里,有20多秒都在prefill,实际generation可能就3-4秒。
结论:agent场景下prefill性能 > generation性能。 如果你只是跑一个简单的chatbot,prompt短,MLX的generation速度其实还行。但一旦上了agent框架(Hermes、OpenClaw、AutoGPT之类的),系统提示词动辄上万token,prefill就成了致命瓶颈。M4 Max MLX在这个场景下基本不可用,只能当备机。
综合评价
主力:DeepSeek V4 Flash
- 太便宜太好用了,没有不用它的理由
- 稳定在4-30秒区间,几乎没有失误
- 解释详细风格友好,日常高频使用完全够
- 5个测试里没翻过车,质量稳定
代码参谋:Claude Code(Opus/Sonnet)
- 不直接当主力模型用,而是通过 Hermes 的 skills 机制调用
- 所有涉及代码的任务,DS Flash 完成主要工作,Claude 负责参谋和验证
- Opus 代码质量碾压(15行decorator vs 别人30+行),复杂SQL最快最准
- Sonnet 速度更快(中等代码10.4s全场最快),质量也接近Opus
备用:Qwen 5090
- 完全免费零API费用,prefill性能碾压
- 日常不怎么用——DS Flash 够便宜了没必要折腾本地
- 真正的用途是留给 ComfyUI 之类的图片/视频生成工作流
- 5090 的 32GB 显存和 CUDA 算力,跑推理有点浪费,跑 SD/Flux/Wan 才是正经事
DS Pro:没有存在感
- 没有一项测试比Flash快
- 质量跟Flash差不多,有时还不如
- 留在降级链里当最后的兜底,平时不会主动切过去
M4 Max MLX:准备退了
- 质量跟5090一样(同模型),但速度慢2-10倍
- prefill是致命瓶颈——Hermes系统提示词6000+ tokens,每次请求光prefill就要20-25秒
- M4 Max 36GB 跑 27B MLX 4bit,能跑但体验太差
- 36GB统一内存也不够上更大的模型,上不去下不来
- 结论:卖了吧。这个价位不如加钱上 M4 Ultra 或者直接用云端API
技术补充:
Claude Code 代理
Claude Code 是个CLI工具不是API,没法直接给Hermes当provider用。所以写了个FastAPI服务把 claude -p 命令包装成 OpenAI 兼容的 /v1/chat/completions 接口,跑在 localhost:8765,注册成 macOS launchd 服务开机自启、挂了自动重启。这也是Claude code 帮我写的 
支持 --model opus 和 --model sonnet 两个档位,通过请求体里的 model 字段自动路由。
系统提示词消毒
Hermes发请求的时候会注入自己的系统提示词(身份信息、人设、工具说明等),如果直接透传给Claude会有风险被收取API所以代理层做了一层自动替换:
Hermes Agent → AI assistant
NousResearch → (删除)
nousresearch.com → (删除)
HERMES.md → project rules
SOUL.md → personality config
delegate_task → subtask
hermes-cli tools → available tools
kawaii assistant → helpful assistant
nya~ desu~ → (删除)
不是简单的正则删除——会留下 "You are , a helpful assistant by ." 这种残句。所以做成了带上下文的替换,比如 (?:Visit )?nousresearch\.com(?:\s+for\s+more\s+info)? 这种模式,把整个句子片段干净地替换或删除。
Claude完全不知道请求来自Hermes。
模型名的坑
模型名一开始叫 claude-code-cli,结果Hermes的provider自动检测看到名字里有 claude,直接归类为Anthropic provider,然后用Anthropic Messages API格式发请求——代理只支持OpenAI chat completions格式,直接404。
改名叫 local-code-agent 就好了。这个坑踩了半小时。
以上。有问题评论区聊。