产品发布
0.1.x 十天走完:十四个版本搭起来的地基

十天,十四个版本。0.1.x 系列是一次地基工程——砍掉一半驻留内存,上线 26 个模型包,覆盖十一个平台目标,把空闲卸载从「功能存在」推到「全链路可用」。这篇文章记录它究竟建了什么。
十天前,OpenASR 0.1.0 作为一个仅支持 macOS 的应用发布,模型目录很小,承诺只有一个:音频转写完全在本地完成,没有例外。十四个版本之后,0.1.14 为这个系列画上句号。这中间的工作谈不上戏剧性——都是些不起眼的地基活儿,但正是它们让后面那些有意思的事情成为可能。以下是这轮冲刺实际做了什么,以及对照最初要解决的问题,做到了几分。
内存:砍一半
0.1.0 收到的最大资源抱怨是驻留内存。守护进程同时加载离线和流式两条路径时,以 qwen3-asr-0.6b 为例,大约持有 2.8 GiB 的权重——而且是两份,因为两套栈各自带了一个独立的执行器。到 0.1.13,离线和流式调度共享同一个进程级执行器实例。同一个模型,同一份权重,只加载一次。端到端实测:约 1.8 GiB,降幅约 37%。
这是最大的一笔,但更小的削减也在累积。ggml 调度器的分配器现在在 FireRed、Dolphin、Moonshine 的计算图之间复用,不再逐图分配。解码运行时缓存加了上界。logits-head 缓存加了上界。能力探测改为缓存已解析的 pack 元数据,而不是每次调用都重新解析(p50 下降约 22%)。这些单拎出来哪个都不算新闻,合在一起,把守护进程从一个「会不断膨胀的东西」变成了一个「能装进去的东西」。
空闲卸载:让它真正能用
0.1.0 的守护进程加载模型后就一直持有,不会释放。设计意图从一开始就是空闲后卸载——没人在听写时把 RAM 还回去——但实现上有缺口。0.1.12 给 idle_unload 加了默认值(10 分钟),缺口随即暴露:Qwen3-ASR 的线程本地 decoder 缓存在卸载后残留,流式预热路径在驱逐后没有重新预热,X-ASR 的池化运行时根本没有被驱逐。
每个缺口对应一个版本。到 0.1.14,空闲卸载的完整周期已经端到端验证过:一次真实卸载释放约 765 MiB,下一次请求按正常冷加载代价重新加载、没有额外惩罚,并且每个 attach 上挂了一个 watchdog,确保卡住的 decode worker 不会楔死卸载计时器,也不会让后续会话排队等在它后面。如果一个 worker 被反复遗弃,守护进程会计数并大声报错。从「功能存在」到「功能在每个声称支持的地方都能用」,走了五个补丁版本。
二十六个模型,一条拉取链路
0.1.0 的模型目录刻意保持精简。在整个系列期间,模型家族扩展到覆盖 Whisper、Qwen3-ASR、Cohere、Dolphin、Moonshine、SenseVoice、X-ASR、FireRed 以及若干 CTC 家族——总计二十六个公开 pack。FireRedPunc 带来了中文标点恢复能力,同时接入批量和流式两条路径。Dolphin 获得了尺寸泛化的运行时,解锁了 dolphin-cn-dialect-base。所有 pack 都经由同一条签名目录拉取链路到达:显式执行 openasr pull,sha256 校验,没有静默下载。
一套真实模型的 CI 回归网络现在会在每次提交时,对所有支持的模型家族跑金标准参考转写。如果准确率回退,发布门禁直接拦住。这套网络在 0.1.0 时并不存在。
十一个目标平台,一套核心
首个版本只发布了 macOS arm64。到 0.1.x 结束时,预构建二进制覆盖了 macOS arm64 与 Intel、Linux x86_64 与 arm64(glibc 和 musl)、以及 Windows x86_64 的 CPU、Vulkan、CUDA、AMD HIP/ROCm 变体——总计十一个平台/GPU 组合。桌面应用也跟上了:今天的 Windows 版发布是另一篇文章的事。
发布归档现在附带 SLSA 构建来源证明(gh attestation verify),守护进程的自签名 TLS 身份在重启后持久化,这样已配对的远程客户端的 TOFU pin 不会因为切换模型而失效。
那些不起眼但重要的事
有些改动很难归入某条叙事线,但分量不轻。safetensors 导入解析器——被十四个模型家族共用——针对恶意构造的头部、重复键、以及偏移/尺寸不匹配做了加固。五个重复的 f16-to-f32 解码例程合并为一个正确实现,此前五个里有两个对 subnormal 的处理是错的。native_transcribe 中三条独立的 finalize 调用链合并为一条。verbose_json 响应现在携带时长、分段 ID、以及一个 words 数组,错误信封也更严格,更贴近 OpenAI 的接口契约。
这些都不让人兴奋。但它们中任何一个如果是错的,那些让人兴奋的功能就不可靠。
0.1 完成了它的本职
0.1.x 系列的目标不是做功能,而是让已有的功能值得信赖。内存有了上界。空闲卸载能用了。拉取链路对每个模型家族都有测试覆盖。守护进程学会了大声报错而不是悄悄失败。平台矩阵从一个扩展到十一个。
这就是 0.2 将要站上去的地基。接下来的工作形态会不一样,而它的起点,是一块被踩过十四遍的地面。