花30分钟让Hermes自己装了个本地耳朵:效果不输Whisper

lxiol

原文链接:https://mp.weixin.qq.com/s/sauDpsvphLjDB8PNs0udlA

本文记录了 Hermes Agent 自主配置 FunASR 本地语音输入的全过程。从环境搭建、HTTP 服务编写,到 Hermes STT 对接和按需自动启动,全部由 Hermes 自己完成。含实测显存数据和踩坑记录。

花30分钟让Hermes自己装了个本地耳朵

效果不输Whisper

2026年6月18日

✦ ✦ ✦

摘要: 本文记录了 Hermes Agent 自主配置 FunASR 本地语音输入的全过程。从环境搭建、HTTP 服务编写,到 Hermes STT 对接和按需自动启动,全部由 Hermes 自己完成。含实测显存数据和踩坑记录。

本文适合: 有 GPU 的 Hermes 用户,想让 Agent 具备离线语音输入能力。
本文不适合: 纯 CPU 用户、不想碰 Python 环境的小白。

✦ ✦ ✦

跟 Hermes 说想试试语音输入。它翻了一下文档,回来告诉我:TTS 直接就能用,但 STT 官方支持的方案——OpenAI Whisper、ElevenLabs Scribe、Mistral Voxtral——全是付费接口,按分钟计费。

不过这些方案也可以本地部署,不想走在线 API 的话,还有别的路。Hermes 自己查了一圈,选了 FunASR。

然后它就开始自己搭了。

选哪个模型

Hermes 选了阿里巴巴达摩院的 FunASR,用的 Nano 系列模型(Fun-ASR-Nano-2512),专门为本地部署优化过。里面带了一个 Qwen3-0.6B 做语言理解层,对技术术语的识别比纯声学模型好不少。

实测结果:

  • 模型文件:2.1 GB(单文件 model.pt)

  • 显存占用:约 3.6 GB(RTX 5070 Ti 16GB,实际转录后稳定值)

  • 首次加载:60-90 秒

  • 转录延迟:1-2 秒(首次加载后)

3.6 GB 的显存占用,看自己的卡够不够用就行。如果吃紧,FunASR 还有更轻量的版本,换模型改一行代码的事。

第一步:装环境

Hermes 发现自己手头有现成的 Python 3.12 + PyTorch + CUDA 环境,直接复用。如果从零开始,它也准备好了创建命令:

python -m venv funasr_env
funasr_env\Scripts\activate
pip install torch torchvision torchaudio –index-url https://download.pytorch.org/whl/cu126
pip install funasr fastapi uvicorn pydantic

五行命令,环境搞定。

第二步:搭 HTTP 服务

FunASR 的标准用法是每次调用加载一次模型。但 3.6 GB 的东西每次加载 90 秒——Hermes 觉得这不合理。

它拆成了两部分:一个常驻的 HTTP 服务,一个轻量的客户端脚本。

服务端代码几十行:

from funasr import AutoModel
from fastapi import FastAPI
import uvicorn

app = FastAPI()
model = AutoModel(
    model=”Fun-ASR-Nano-2512”,
    trust_remote_code=True,
    device=”cuda:0”,
)

@app.post(“/transcribe”)
def transcribe(audio: str, language=”中文”):
    res = model.generate(input=[audio], language=language)
    return {“text”: res[0].get(“text”,””).strip()}

uvicorn.run(app, host=”127.0.0.1”, port=18888)

启动后访问 http://127.0.0.1:18888/health 看加载状态,POST /transcribe 传音频路径返回文字。正式版还加了启动预加载、全局单例和异常兜底。

第三步:对接 Hermes

Hermes 的 STT 配置在 config.yaml 里。它自己改了配置:

stt:
  provider: funasr
  providers:
    funasr:
      command: .venv\Scripts\python.exe
        scripts\funasr_stt_wrapper.py {input_path} {output_path} {language}
      timeout: 60
      language: “中文”

STT 系统的工作方式:录完音 → 调用指定命令 → 传音频路径、输出路径、语言 → 读写回的结果文件。中间那一跳由客户端脚本完成。

第四步:客户端脚本

客户端的职责:收音频 → 转 WAV → POST 给 HTTP 服务 → 写回结果。

但 Hermes 加了一个关键逻辑——

如果 HTTP 服务还没跑,自动启动它。

def _ensure_server():
    s = socket.socket()
    try:
        s.connect((“127.0.0.1”, 18888))
        s.close()
        return  # 已经在跑了
    except ConnectionRefusedError:
        pass

    # 没跑——启动服务进程
    sp.Popen(
        [python, server_script],
        stdout=sp.DEVNULL, stderr=sp.DEVNULL,
    )

    # 等模型加载完
    deadline = time.time() + 120
    while time.time() < deadline:
        try:
            resp = urllib.request.urlopen(
                “http://127.0.0.1:18888/health
            )
            info = json.loads(resp.read())
            if info.get(“model_loaded”):
                return
        except:
            pass
        time.sleep(2)

效果就是:输入 /voice on,服务自动启动,模型开始加载。加载完以后,每一次都是秒回。

不需要预启动,不需要 cron job,不需要记住开服务。一切按需。

第五步:GPU 释放机制

模型常驻 GPU 是个问题——3.6 GB 说多不多,说少也不少。Hermes 加了两道保险:

1. 空闲自动退出。 服务端有一个后台计时器,每 30 秒检查一次:如果距离最后一次转录请求已经超过 5 分钟,自动终止进程,GPU 显存释放。

2. 手动关闭。 在客户端脚本传 --shutdown 参数,会向服务端发 POST /shutdown 请求,优雅退出。

对应服务端代码:

_idle_timeout = 300 # 5 分钟

@app.post(“/shutdown”)
def shutdown_endpoint():
  threading.Timer(0.5, lambda: os._exit(0)).start()
  return {“status”: “shutting_down”}

也就是说:用完不说话,5 分钟后 GPU 自动归还;想立刻释放,传个参数就行。不用手动找进程杀。

效果测试

配置完成后,对着话筒说了一句「你现在可以听得到我的语音吗」。

回车。

{“text”:”你现在可以听得到我的语音吗”}

一字不差。

后续对话也很流畅。说完等 1-2 秒就有回应。数据在自己机器上,不用走外部服务。

踩坑记录

音频路径的 8.3 短文件名问题。 Hermes 录下来的 WAV 路径有时带着 ADMINI~1 这种 Windows 短名。FunASR 的 os.path.isfile() 不认这个路径,第一次转录直接失败。Hermes 发现后在客户端加了 os.path.realpath() 显式解析。

后台不能弹窗。 sp.Popen 传了 creationflags=sp.CREATE_NO_WINDOW。不然每次 /voice on 弹一个黑窗口。

超时兜底。 转录接口设 30 秒超时,模型加载等 120 秒。超过上限硬试一次。实测首次加载 60-90 秒,很少超时——但兜底必须有。

常见问题

Q:没有 GPU 能用吗?

A:支持 CPU 模式,但转录速度慢 5-10 倍。一次 3 秒的音频可能要 10 秒才能返回。

Q:跟 Faster-Whisper 比怎么样?

A:中文场景下 FunASR Nano 的准确率略高,特别是对技术术语的识别。Faster-Whisper 的优势是多语言和社区生态。

Q:TTS 也一起搞定了吗?

A:Hermes 的 TTS 直接用 Edge 在线接口,免费稳定。本文只涉及 STT 部分。

一句话总结

本地语音输入不是必须的——但在你恰好有 GPU、恰好用 Hermes 的时候,跟它说一声,半小时就能有一套离线可用的语音输入。

之后每次 /voice on,说就完了。

⚜ ⚜ ⚜

以上。有什么问题欢迎留言讨论。

— 完 —


💬 本文评论区已开启,但暂无读者留言。

本文转载自微信公众号,如有侵权请联系删除。

  • 标题: 花30分钟让Hermes自己装了个本地耳朵:效果不输Whisper
  • 作者: lxiol
  • 创建于 : 2026-06-22 11:44:12
  • 更新于 : 2026-06-30 17:05:34
  • 链接: https://blog.lxiol.cn/2026/06/22/花30分钟让Hermes自己装了个本地耳朵效果不输Whisper/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
目录
花30分钟让Hermes自己装了个本地耳朵:效果不输Whisper