长音频转写的工程实践:分片、轮询与断点续传

长音频转写的工程实践:分片、轮询与断点续传

把一段两小时的会议录音丢给语音转文字(STT)接口,新手工程师通常在三个地方翻车:请求超时、单次转写内存爆掉、失败重试只能整段重来。这篇把一套经过实战的分片转写流水线拆开讲。

一、为什么必须分片

长音频直传有三个结构性问题:

  • 超时上限:同步接口普遍 60 秒墙,两小时音频根本进不去;异步接口虽无此墙,但单任务越大,失败重跑的代价越高
  • 内存峰值:整段载入+解码,8 小时播客能吃掉数 GB 内存
  • 重试粒度:95% 成功 + 5% 失败 = 100% 重来,这是最亏的

分片把失败半径从"整段"缩到"单片",三个问题一起解。

二、怎么切:固定窗口 vs 静音检测

两种切法:

切法 实现 优点 缺点
固定窗口 每 60~120 秒一刀 实现零成本 词被拦腰切断,识别质量受损
静音检测 按 VAD 找静音点下刀 词界完整,质量最好 依赖 VAD 参数,安静录音会切不开

工程折中:固定窗口 + 窗口间 1~2 秒重叠。重叠区转写后按时间戳去重,实现简单,词被切断的概率大幅下降。除非业务对断句质量极敏感,不必上 VAD。

CHUNK_SEC, OVERLAP_SEC = 90, 2

def slice_audio(duration):
    starts = list(range(0, duration, CHUNK_SEC - OVERLAP_SEC))
    return [(s, min(s + CHUNK_SEC, duration)) for s in starts if s < duration]

三、轮询:指数退避 + 状态机

异步转写提交后进入轮询。两个要点:

def poll_task(task_id, client):
    wait = 2.0
    while True:
        state = client.task_status(task_id)   # PENDING/RUNNING/DONE/FAILED
        if state in ("DONE", "FAILED"):
            return state
        time.sleep(wait)
        wait = min(wait * 1.6, 30)           # 指数退避,封顶 30s
  • 指数退避:刚开始 2 秒一查,逐步拉长到 30 秒封顶——短任务快速收口,长任务不空转
  • 总超时必须有:单片转写超过 10 分钟视为挂死,走重试逻辑,防止死循环

四、断点续传:分片级 checkpoint

流水线任意时刻可能被打断(进程重启、机器发布)。把每片状态落盘,重启后跳过已完成的片:

def transcribe_all(chunks, store):
    results = {}
    for i, (start, end) in enumerate(chunks):
        if store.done(i):                    # checkpoint 命中,跳过
            results[i] = store.load(i)
            continue
        task = client.submit(chunk_file(i))
        if poll_task(task.id, client) == "DONE":
            store.save(i, client.fetch(task.id))
            results[i] = store.load(i)
        else:
            raise RetryableChunk(i)          # 只重试这一片
    return merge(results)                    # 按时间戳合并 + 重叠区去重

checkpoint 用一个 JSON 文件就够,别过度设计。核心收益:任何一片失败,代价只是那一片。

五、选接口时看三个参数

  • 单次时长上限:决定分片窗口的硬顶
  • 异步任务支持:有没有任务号+查询接口,决定轮询模式还是同步等待
  • 并发配额:分片转写是并发友好型负载,QPS 配额直接决定总耗时

按量计费的 STT 平台(如算邻坊 suanlinfang.cn 的随心语音转文字)这类按秒计费、支持异步任务的接口,配这套流水线刚好——分片天然对账,转多少秒付多少秒,失败片重试不产生重复计费。

六、小结

长音频转写的工程化 = 分片缩失败半径 + 退避轮询收状态 + checkpoint 保断点。三者都是几十行代码的事,但没有它们,转写服务在生产环境就是定时炸弹。上一篇《按量计费的工程账》聊了钱怎么算,这篇聊活怎么干,两篇合起来是一套完整的按量服务使用姿势。

posted @ 2026-11-09 10:52  吴键WJ  阅读(4)  评论(0)    收藏  举报