tiny-audio 发布:可花 25 美元训练的语音转文字系统
tiny-audio, nanoGPT for speech-to-text
tiny-audio 发布一套可低成本训练的语音转文字系统,把冻结的预训练语音编码器接到预训练 LLM 上,只训练约 80M 参数的投影层。仓库发布的模型在 LibriSpeech test-clean 上 WER 为 1.8%,在 12 个基准共 11,822 条样本上为 7.4%。
一个只需 25 美元即可训练的语音转文本系统。
Tiny Audio 将一个冻结的预训练语音编码器与一个预训练 LLM 连接起来,中间通过一个小型可训练投影器。从此仓库发布的模型在 LibriSpeech test-clean 上达到 1.8% WER,在 12 个基准测试中平均 7.4%(汇总 11,822 个样本),而仅训练约 80M 参数。代码库小到一下午就能读完,你可以在笔记本电脑上大约五分钟内跑完一个训练循环。
30 秒内试用
无需安装:打开 在线演示,录制自己的声音或上传文件,即可获得转录文本。
在 Python 中:
pip install "transformers>=5.0" peft torch torchaudio librosafrom transformers import pipeline pipe = pipeline( "automatic-speech-recognition", model="mazesmazes/tiny-audio", trust_remote_code=True ) print(pipe("audio.wav")["text"]) # The quarterly revenue grew by 12% according to Dr. Smith.
输出带有标点、大小写和数字格式,无需后处理步骤。输入可以是文件路径、URL 或 16 kHz 的 numpy 数组。权重为 bf16,因此大约需要 6 GB 的 GPU 或 Apple Silicon 内存。
不止于纯文本
# Word-level timestamps (forced alignment) pipe("audio.wav", return_timestamps=True) # {"text": "hello world", "words": [{"word": "hello", "start": 0.0, "end": 0.5}, ...]} # Who spoke when (speaker diarization) pipe("meeting.wav", return_speakers=True, num_speakers=2)
Nemotron-3-Diarization 找到的每个说话人都会在其他人被静音的音频副本上单独转录,每个词都属于其来源的流。这是 NeMo 的 masked_asr 配方的零样本移植;两个流同时听到的词只保留一次。每个说话人在 ASR 中的成本大约等于其自己的说话时间,单说话人音频不进行掩蔽转录。重叠仅部分处理:说话人轮次内其他人的语音会留在该说话人的流中。
说话人日志需要从 main 安装 transformers(pip install git+https://github.com/huggingface/transformers),直到下一个版本发布。对于逐令牌流式输出,请参阅 ASRModel.generate_streaming。模型卡涵盖了批处理和 GPU 设置。
作为 RunPod 上的 HTTP API
ta serve 将模型置于批处理 HTTP 服务器之后:同时到达的请求共享 GPU 批次,因此吞吐量随负载增长(在 RTX 4090 上,128 个并发请求时约为实时的 460 倍)。要在 RunPod GPU 上运行它:
poetry run ta runpod up --serve # create an inference pod; prints <POD_ID> poetry run ta runpod wait <POD_ID> # prints <HOST> <PORT> poetry run ta runpod deploy <HOST> <PORT> # sync the project, install the fast kernels TINY_AUDIO_API_KEY=my-secret poetry run ta runpod serve <HOST> <PORT> --no-attach # Ready when https://<POD_ID>-8000.proxy.runpod.net/health answers (a few minutes: it compiles first)
没有 TINY_AUDIO_API_KEY 时,服务器对任何拥有 URL 的人开放。ta serve 也可以在本地运行,支持 CUDA、Apple Silicon 或 CPU。
将音频作为请求体发送,选项放在查询字符串中:
curl -X POST "https://<POD_ID>-8000.proxy.runpod.net/?return_timestamps=true" \ -H "Authorization: Bearer my-secret" \ -H "Content-Type: application/octet-stream" \ --data-binary @audio.wav
import httpx response = httpx.post( "https://<POD_ID>-8000.proxy.runpod.net/", params={"return_speakers": "true", "num_speakers": "2"}, content=open("meeting.wav", "rb").read(), headers={"Authorization": "Bearer my-secret"}, timeout=600, ) print(response.json()["text"])
- 选项:
return_timestamps、return_speakers、num_speakers和max_speakers,与管道中相同。响应是管道返回的同一个字典。 - JSON 请求体:要改为发送 JSON,请使用
{"inputs": "<base64 audio>", "parameters": {...}}。 - 音频格式:任何 FFmpeg 能读取的格式。
- 错误:音频或选项错误时返回
400和{"error": ...},密钥错误时返回401。 - 其他端点:
GET /health和GET /stats(批大小和 GPU 时间)。
RunPod 的 HTTP 代理拒绝超过 500 MiB 的请求体,并会丢弃任何耗时超过 100 秒的请求。对于长录音,请发送 16 kHz 单声道 FLAC:
ffmpeg -i recording.wav -ac 1 -ar 16000 recording.flac
这大约每分钟音频 1 MB,且不会损失准确率,因为服务器无论如何都会将所有内容转换为 16 kHz 单声道。在 RTX 4090 上,45 分钟音频大约需要 10 秒,带说话人标签则需要 21 秒。演示 Space 就是这样调用服务器的。
效果如何?
在 11,822 个样本(每个数据集最多 1,000 个)上的词错误率(%,越低越好),使用此仓库的 ta eval 在 RTX 4090 上与 ta serve HTTP API 对比测量:
| 数据集 | WER |
|---|---|
| LibriSpeech test-clean | 1.84 |
| SPGISpeech | 2.29 |
| TED-LIUM | 3.71 |
| LoquaciousSet † | 6.20 |
| LibriSpeech test-other | 6.38 |
| VoxPopuli | 7.11 |
| Common Voice | 7.18 |
| AMI (IHM) | 8.99 |
| GigaSpeech | 9.06 |
| Earnings22 † | 10.58 |
| People's Speech | 17.59 |
| AMI (SDM) | 23.53 |
| 平均值(12 个数据集) | 8.71 |
| 汇总(11,822 个样本) | 7.42 |
† 留出:训练中未使用此来源的任何数据。
你可以自行核对这些数字,并在相同样本上与商业 API 进行比较:
poetry run ta eval -m mazesmazes/tiny-audio -d loquacious -n 100 # Same samples through a commercial API (also: deepgram, elevenlabs, apple-speech) ASSEMBLYAI_API_KEY=... poetry run ta eval -m assemblyai -d loquacious -n 100
工作原理
Audio (16 kHz) → speech encoder (frozen) → MLP projector (trained) → LLM decoder → Text
- 预训练的语音编码器将音频转换为一系列帧嵌入。
- 一个小的MLP投影器将相邻帧堆叠并映射到LLM的嵌入空间。它是唯一从头训练的部分。
- LLM将这些投影后的帧当作token来读取,并输出转录文本。
编码器、投影器和解码器均可通过配置进行替换。仓库中附带两种配方:
| 配方 | 编码器 | 解码器 | 训练方式 |
|---|---|---|---|
已发布模型(granite_qwen_frozen) |
Granite Speech 470M | Qwen3.5,冻结 + LoRA | 投影器 + LoRA(约80M) |
默认 / 课程配方(stage_1) |
GLM-ASR-Nano(635M) | Qwen3-0.6B,微调 | 投影器 + 解码器 |
训练你自己的模型
免费在笔记本电脑上开始,只有在确认流程可行后才租用GPU。
| 层级 | 数据 | 硬件 | 成本 |
|---|---|---|---|
| 冒烟测试 | 73个LibriSpeech片段 | 你的笔记本电脑(CPU、MPS、CUDA) | 免费,约5分钟 |
| 课程运行 | LoquaciousSet small(约250小时) |
一块租用的GPU,几个小时 | 几个GPU小时 |
| 生产配方 | 十个语料库约300万个片段(> 1 TB) | 一块80 GB GPU,一天或更久 | 数百美元 |
git clone https://github.com/alexkroman/tiny-audio.git && cd tiny-audio poetry install # 1. Smoke test: a real training loop on your laptop poetry run python scripts/train.py +experiments=mps_smoke # 2. Before renting hardware, estimate the VRAM and disk a config needs poetry run ta runpod plan -e stage_1 # 3. Full run poetry run python scripts/train.py +experiments=stage_1
每个设置都是一个Hydra覆盖项,例如
model.projector_hidden_dim=2048或training.use_lora=true。当你对模型满意时,
ta push会将其发布到Hugging Face Hub,ta deploy会将像上面那样的演示放到
Space上。
在RunPod上训练
poetry run ta runpod up -e stage_1 # create a pod with enough GPU for the config poetry run ta runpod wait <POD_ID> # prints <HOST> <PORT> poetry run ta runpod deploy <HOST> <PORT> # sync the project and install dependencies HF_TOKEN=hf_... poetry run ta runpod train <HOST> <PORT> -e stage_1 poetry run ta runpod attach <HOST> <PORT> # watch the run in tmux
通过构建来学习
免费的3.5小时课程将带你走完整个流程:
编码器、投影器和解码器如何组合在一起(包含真实的张量形状)、训练模型、
对照商业API进行评估,并通过实时演示发布它。你需要Python、
命令行和git。该课程训练较小的stage_1配方,而非已发布的模型,因此
your WER will be higher than the table above.
想尝试新的投影器架构、添加数据集或更改代码库?请参阅 CONTRIBUTING.md以获取CLI参考、配置布局和质量门禁。
致谢
- Granite Speech和 GLM-ASR提供音频编码
- Qwen3.5和 Qwen3提供语言建模
- LoquaciousSet提供默认 评估集
许可证
MIT
来源:Hacker News · github.com
