hermes设置菜单和模型列表非常卡

问题

两件事:

  • Hermes 桌面整体操作卡慢,尤其设置菜单和编辑模型列表巨慢。
  • 模型列表里有很多压根不想看到的模型,希望能统一过滤,并且过滤落在更底层,不要蔓延到数据层和 UI 层。

结论(2026-10-25 复盘)

两件事是两个独立的根因,已分别解决,用户验收:UI 速度非常快,问题完全解决。

症状 根因 处置 状态
整机卡、桌面交互迟滞、设置菜单/模型列表巨慢 Electron 未走硬件渲染:NVIDIA EGL 初始化失败后一进软件渲染(SwiftShader),且落下粘滞标记文件,之后每次启动都继续软件渲染 关闭 NVIDIA SwiftShader 回退,删除粘滞标记;渲染进程恢复 GPU 加速 已解决
模型列表里不想看的模型无法在底层统一过滤 后端只有 model_catalog.excluded_providers(provider 粒度),全仓没有模型级排除键;桌面端现有的可见性开关只写浏览器 localStorage,仅作用于 UI 层 结论:不改源码做不到模型级底层过滤;provider 级可配,模型级需落在 inventory.py 那条唯一链路上 已查实(能力边界)

一、卡慢的根因与修法

根因链

Electron 启动
  → GPU 初始化时 NVIDIA EGL 加载失败
    → 自动回退 SwiftShader(纯 CPU 软件渲染)并写出粘滞标记
      → 之后每次启动都直接走软件渲染
        → 渲染主循环把多核 CPU 吃满(实测 300~650% CPU)
          → 整机负载飙升(3 分钟内 5.8 → 11.5),所有 UI 操作排队
            → 设置菜单、模型列表这类重列表页最明显

关键判据:进程参数里能看到 --use-angle=swiftshader,且日志出现 NVIDIA EGL fallback enabled,没有独立的 gpu-process 正常工作。这不是「列表渲染慢」的前端问题——CPU 被软件渲染吃掉了,什么页面都慢。

修法(三步)

  1. 备份环境变量文件(改名带时间戳留档)
  2. 写入 HERMES_DESKTOP_NVIDIA_SWIFTSHADER=0,禁用 NVIDIA SwiftShader 回退
  3. 删除粘滞标记文件 nvidia-egl-fallback.json——不删它,开关改了也回不到硬件渲染

验证判据(重启后):启动日志里 NVIDIA EGL fallback enabled 那行消失;进程参数里不再有 use-angle=swiftshader;CPU 从数百个百分点回落到正常量级。

修复后复测(2026-10-25 12:34,用户已在用)

renderer    16.4%  CPU   RSS 953 MB   ← 正常量级(此前 300~650%)
gpu-process  7.7%  CPU   RSS 177 MB   ← 独立 GPU 进程正常工作
zygote       0.0%  CPU                ← 之前的空转死循环已消失
主进程       1.4%  CPU
系统负载     3.27 / 2.80 / 3.58       ← 从 11.5 回落
粘滞标记     nvidia-egl-fallback.json 不存在

二、模型过滤的能力边界

链路(唯一数据源)

config.yaml: model_catalog.excluded_providers
  → hermes_cli/inventory.py:56  load_picker_context()
    → build_models_payload(excluded_providers=...)
      → list_authenticated_providers(...)
        → 桌面 / TUI / CLI / gateway 全部消费方

这条链是所有模型列表的唯一数据源,在这层过滤才谈得上「不蔓延到 UI 层」。现有配置只能到 provider 粒度:

model_catalog:
  excluded_providers:
    - opencode-go      # 整个 provider 从所有入口消失
    - ds-buy

已验证的事实(grep 源码)

检查项 结果
消费点inventory.py:56 → build_models_payload → 桌面/TUI/CLI/gateway,一次配置四处生效
provider 级排除已实现,匹配 provider slug 或别名(大小写不敏感)
模型级排除不存在:全仓无 excluded_models 或同义键
桌面现有可见性开关写浏览器 localStorage(hermes.desktop.visible-models),只作用于桌面 UI;CLI/TUI/gateway/API 都不认

因此:某个 provider 整块不要 → 现在就能配;只想去掉某些模型 → 不改源码没有配置项。要模型级底层过滤,必须给 model_catalog 加一个模型级排除键,挂在 inventory.py 那条唯一链路上,前端一行不动。

附带一条桌面端既有行为:新模型出现时会走「策展默认规则」而不是默认隐藏(known-models 快照机制)——意味着纯 UI 层的隐藏列表不会自动覆盖新上架的模型,每来一批新模型都要手工再勾一次。这是把过滤放到数据层的另一个理由。

三、教训(沉淀)

  • 先分离层次再动手:整机慢 ≠ 某个页面慢。看 CPU 归属(renderer / gpu-process / zygote)比看 UI 帧率更快定位;zygote 空转与 swiftshader 回退是两个不同故障,别混成一个。
  • 粘滞标记是隐藏关卡:只改开关不删标记文件,回退状态会一直生效。
  • 配置项存在 ≠ 粒度够用:excluded_providers 的真实粒度就是 provider,读源码确认「没有模型级键」比猜更快。
  • 过滤要选在唯一数据源上:同一份模型清单有四个消费方,只有后端 build_models_payload 那一层能一次覆盖全部。