语音转文字计费:你实际在为什么付费
转录计费看起来很简单——每分钟一个单价——然后第一张账单就和预估对不上。差额几乎从来不是单价问题,而是你没意识到自己发过去的那些分钟:静音、重复、重试,以及根本没人读的文件。
计价单位是音频分钟,不是字数
从这里开始,因为它解释了大部分意外。你付的是上传音频的时长,不是返回文本的多少。
值得记住的几个推论:
- 一分钟静音和一分钟密集语音价格相同。
- 没有人说话的录音仍然按全长计费,尽管响应是空的。
- 五分钟文件里只有十秒语音,也按五分钟收费。
- 说得更快不会更便宜。把文件剪短才会。
下面几乎每一条优化都是同一个思路的变体:少发音频,而不是少说话。
意外的分钟数从哪里来
| 来源 | 典型浪费 | 解决办法 |
|---|---|---|
| 通话录音首尾的静音 | 10–30% | 发送前用 ffmpeg 剪掉 |
| 等待音乐和语音菜单 | 5–20% | 切掉接通之前的片段 |
| 崩溃之后同一个文件发了两次 | 最高 100% | 幂等流水线,跳过已完成文件 |
| 留在生产代码里的测试调用 | 不定 | 单独的密钥,盯住客户后台 |
| 没有人打开过的转录 | 常常是大头 | 按需转录,而不是全部转录 |
最后一行通常是最大的一项,也是最不技术的一项。团队常常因为「转起来很容易」就把整个存档转完,然后只用了其中百分之二。
估算自己的支出
不要从价目表外推——去测量自己的音频。整个计算只有两个数字:
ffprobe -v error -show_entries format=duration -of csv=p=0 sample.mp3
import pathlib, subprocess
def minutes(p):
out = subprocess.run(["ffprobe", "-v", "error", "-show_entries",
"format=duration", "-of", "csv=p=0", str(p)],
capture_output=True, text=True).stdout
return float(out) / 60
month = sum(minutes(p) for p in pathlib.Path("recordings").glob("*.mp3"))
print(f"{month:.0f} min per month")
乘以单价就是月度金额。几个实践中站得住的参照:每天 200 通、每通四分钟的客服线路,大约每月 16 000 分钟;每周一期的播客大约 4 小时;十个人每天开半小时会,大约 600 分钟。
套餐加超量,以及它为什么存在
多数套餐由「含一定分钟数的月费」加「超出部分的每分钟单价」组成。这个算术值得算一次:
bill = monthly_fee + max(0, used_minutes - included_minutes) * rate
要避开两种失败模式。买了远高于自己用量的套餐,等于为用不完的分钟付钱——包内分钟不会结转。而在高用量下继续按纯分钟付费,则错过了套餐代表的折扣。在决定之前,先看三个月的真实用量。
套餐上的硬性限额是一个安全特性,不是限制:它能阻止一个失控的循环生成一张没人批准过的账单。开发阶段请把它打开。
调用 API 还是自建 GPU
诚实的比较不是「每分钟单价对零」。自建只是把成本从一个账目条目挪成一组容易被忘记的东西:
| 成本项 | API | 自建 GPU |
|---|---|---|
| 每分钟音频 | 单价 | 0 |
| 硬件 | 0 | 显卡加整机,按年摊销 |
| 电费和机房 | 0 | 持续支出,空转也一样 |
| 搭建与维护 | 0 | 工程师时间,长期投入 |
| 空闲时间 | 免费 | 照常付费 |
盈亏平衡点取决于利用率,而不是总量。一天只跑几小时的显卡输给 API,因为那二十个空闲小时你也在付钱。全天候满载的显卡则赢。介于两者之间时,决定因素通常是:你愿不愿意为一台机器在凌晨三点负责。
还有第三个理由,和钱无关:有些数据不允许离开自己的边界。那是硬性要求,不是优化,它自己就能决定答案。
在不损失质量的前提下压低账单
- 剪掉静音。通话录音上最便宜的一项改动——常常直接省下 10–30%,且完全不影响质量。
- 不要转录没人读的东西。按需转录,或只转录超过某个时长的通话,然后观察大家实际打开的是什么。
- 让流水线幂等。崩溃后重做已完成的工作是纯粹的浪费;跳过已完成文件就消除了它。
- 开发用单独的密钥。测试流量混进生产数字里,会同时掩盖两边的问题。
- 每周看用量,而不是每月。一个循环重复发送同一个文件,第一天就很显眼,到第三十天就很贵了。
# 剪掉录音首尾的静音
ffmpeg -i call.mp3 -af silenceremove=start_periods=1:start_threshold=-45dB:stop_periods=-1:stop_threshold=-45dB:stop_duration=2 short.mp3
用你自己的录音试一试。 注册只需一分钟,免费额度足够判断识别质量。
免费获取 API 密钥常见问题
是按音频分钟计费还是按文字字数?
按你上传的音频分钟计费。返回文本的长度不影响价格,这正是静音和等待音乐与语音同价的原因。
没有声音的录音也要付费吗?
要,音频仍然被处理了,尽管响应是空的。发送前剪掉静音是最直接的解决办法。
失败的请求会被计费吗?
返回错误的请求不计音频分钟。真正花钱的是重复一次已经成功的转录,所以可续跑的流水线很重要。
在自己的 GPU 上跑 Whisper 更便宜吗?
只有在高利用率下才更便宜。一天大部分时间空转的显卡,把硬件、电费和维护算进去之后就输给按分钟计费。全天候满载才是自建取胜的场景。
怎样避免收到意外账单?
第一批任务之前用 ffprobe 估算用量,开发期间保持套餐硬限额开启,并且每周而不是月底去客户后台看用量数字。
相关阅读
- 如何为音频存档搭建批量转录流水线 — 转录上万条录音而不丢失任何一条:任务队列、并发控制、重试策略、崩溃后续跑,以及如何把账单控制在预期之内。
- 如何从 OpenAI Whisper API 迁移到其他服务 — OpenAI Whisper API 迁移指南:代码要改哪两行、响应和错误格式有何差异,以及切换生产流量之前如何对比识别质量。
- 如何把通话录音转成文字 — 分步教程:几分钟内通过 API 把电话录音转成文字,包含 Python 和 C# 代码示例、响应格式说明,以及常见错误的处理办法。