Skip to content

feat: 新增小米 MiMo 云端转写引擎(切片并发 + 断点续跑) - #99

Open
fatmmouse wants to merge 1 commit into
lanbinleo:mainfrom
fatmmouse:feat/mimo-provider
Open

feat: 新增小米 MiMo 云端转写引擎(切片并发 + 断点续跑)#99
fatmmouse wants to merge 1 commit into
lanbinleo:mainfrom
fatmmouse:feat/mimo-provider

Conversation

@fatmmouse

Copy link
Copy Markdown

这个 PR 做了什么

新增小米 MiMo(mimo-v2.5-asr)作为第四个转写引擎。它走的是 OpenAI 兼容的 chat completions + input_audio 协议,所以实现上和现有 provider 结构一致,只多了一个 mimo extra(依赖仅 openai)。

配置项和其他云端引擎一样走 bootstrap,README / CHANGELOG(中英)都已同步。

长音频的处理

单请求整段音频喂不动一个半小时的视频,所以按 60 秒切片,然后:

  • 并发转写--workers / 配置项 mimo.workers 控制并发数,默认 4
  • 单片退避重试。并发调高容易撞服务端限流(HTTP 429),实测 --workers 8 跑 94 片会挂 9 片;重试之后偶发限流可以自愈,不至于让整个长任务作废
  • 切片结果缓存.b2t/cache/mimo/,key 是切片音频内容的哈希 + 模型 + 语言。重跑时重新切出来的分片字节一致,所以中断后原样重跑只会转缺失的部分,不会重复计费。换模型或语言会正常 miss

实测:93 分钟的讲座,--workers 6 约 25 分钟出稿;中断重跑补 9 个切片只花了几分钟。

顺带修了一个 bug

library.pyresult.metadata.get("download", {}).get("title"):本地文件转写时 download 这个 key 是存在的、值为 None.get 的默认值不会生效,于是 None.get(...) 抛错。改成 (... or {})。这个和 MiMo 无关,是测试本地文件时撞到的,如果不希望混在这个 PR 里我可以拆出去。

测试

新增 tests/test_mimo.py(5 个用例,用假 client 不打网络):缓存命中不重复请求、不同模型/语言不会错误复用缓存、未配置缓存目录时不缓存、重试成功后结果入缓存、重试耗尽正常抛错。

全量测试 61 passed。另外用真实 API 端到端跑过 B站视频和本地音频。

一个想听听意见的点

--workers 现在挂在通用的 transcribe 命令上,但目前只有 MiMo 会切片、用得到它,其他 provider 传了不生效。是保持现状(后续有别的 provider 支持并发时直接复用),还是您更希望只留配置项、不暴露成 CLI 参数?我按您的意见改。

MiMo (mimo-v2.5-asr) is reached over an OpenAI-compatible chat
completions endpoint with input_audio, so it slots in next to the
existing providers and only needs the new `mimo` extra.

Long audio is the interesting part. A single request per file does not
scale to hour-long lectures, so the audio is split into 60s chunks:

- chunks run concurrently; `--workers` / `mimo.workers` sets how many
  (default 4, which stays clear of the API's rate limit)
- each chunk retries with backoff, so one 429 in the middle of a
  90-minute job no longer discards everything transcribed so far
- successful chunks are cached under .b2t/cache/mimo, keyed by chunk
  audio content plus model and language, so re-running an interrupted
  job only transcribes (and pays for) what is missing

Also fixes an unrelated crash found while testing local files: when a
transcription has no download step, metadata["download"] is None, and
`.get("download", {})` returns None rather than the default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant