Audex 开源:把语音、声音和文本塞进同一个 Transformer 解码器

2026-07-08 35 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

NVIDIA 研究团队开源的 Nemotron-Labs-Audex-30B-A3B,简称 Audex,值得音频 AI 开发者认真看一眼。它不是再做一个“语音模块 + 文本大模型”的拼装系统,而是把文本 token 和量化音频 token 放进同一个纯解码器 Transformer 里处理,用 MoE 架构承接更大的模型容量。

这类统一音频-文本模型的意义很直接:开发者不再只把音频当作 ASR 的输入,或者把语音合成当作 TTS 的输出,而是可以围绕“音频 token 也是语言的一部分”来设计交互、检索、标注和生成流程。

架构亮点:单一解码器,而不是多模块流水线

Audex 的核心设计可以概括为三点:

  • 基于纯文本 MoE 大语言模型架构构建。
  • 使用单一 Transformer 解码器统一处理文本 token 与量化音频 token。
  • 让音频输入能够平滑投影到文本嵌入空间,从而进入同一套推理路径。

这和传统语音系统的工程形态不同。过去常见做法是:

audio -> ASR -> text -> LLM -> text -> TTS -> audio

这个链路清晰、可控,但每一步都会丢信息。ASR 会把语调、停顿、环境声、说话人状态压扁成文字;LLM 只看到转写文本;TTS 再重新生成声音。对于会议纪要、客服质检、播客摘要,这可能够用。但对于语音情绪、非语言声音、音乐片段、音频问答这类任务,文字中转会变成瓶颈。

Audex 的路线更接近:

[text tokens + quantized audio tokens] -> unified decoder -> text/audio-related output

这里的“统一”不是宣传词,而是会改变应用边界:模型可以在同一上下文里理解文字提示和音频片段,不必把音频先强制翻译成文字。

MoE 的现实含义:容量更大,但部署要更清醒

Audex 名称里的 30B-A3B 暗示它是一个大容量模型,同时具备激活参数较少的 MoE 特征。MoE,也就是混合专家模型,通常会让模型总参数规模变大,但每次推理只激活部分专家,从而在能力和计算成本之间做折中。

对开发者来说,这里有两个判断点:

  • 它适合研究、评测和高价值音频任务原型,不一定适合直接塞进低成本在线链路。
  • MoE 降低的是每 token 的激活计算,不等于显存、加载、调度和服务复杂度都消失。

如果你准备试用类似模型,别只看“激活参数”。还要确认:

  • 权重格式和推理框架是否已经支持。
  • 是否需要特殊音频 tokenizer 或 processor。
  • 音频 token 的上下文长度会不会迅速吃掉窗口。
  • 批处理时不同音频长度是否导致吞吐不稳定。

音频模型的工程成本经常不在模型调用那一行代码,而在前处理、采样率、分段、缓存和延迟控制上。

可以这样实践:先搭一个音频-文本统一接口壳

下面这个示例不是 Audex 官方 API,而是一个可改造的最小项目骨架。它假设模型以 Hugging Face 风格发布,并且提供了 AutoProcessorAutoModelForCausalLM 兼容接口。实际运行前,你需要把 MODEL_ID 改成模型仓库中的真实 ID,并按模型卡要求调整 trust_remote_code、音频采样率和输入字段。

安装依赖:

python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install torch transformers librosa soundfile accelerate

创建 audex_probe.py

import argparse
import torch
import librosa
from transformers import AutoProcessor, AutoModelForCausalLM


def load_audio(path: str, target_sr: int = 16000):
    audio, sr = librosa.load(path, sr=target_sr, mono=True)
    return audio, sr


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--model", default="REPLACE_WITH_AUDEX_MODEL_ID")
    parser.add_argument("--audio", required=True)
    parser.add_argument("--prompt", default="请用中文概括这段音频的主要内容,并指出可能的声音事件。")
    args = parser.parse_args()

    audio, sr = load_audio(args.audio)

    processor = AutoProcessor.from_pretrained(
        args.model,
        trust_remote_code=True,
    )
    model = AutoModelForCausalLM.from_pretrained(
        args.model,
        torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
        device_map="auto",
        trust_remote_code=True,
    )

    # 假设 processor 支持 text + audio 输入。实际字段以模型卡为准。
    inputs = processor(
        text=args.prompt,
        audio=audio,
        sampling_rate=sr,
        return_tensors="pt",
    )
    inputs = {k: v.to(model.device) if hasattr(v, "to") else v for k, v in inputs.items()}

    with torch.inference_mode():
        output_ids = model.generate(
            **inputs,
            max_new_tokens=256,
            do_sample=False,
        )

    print(processor.decode(output_ids[0], skip_special_tokens=True))


if __name__ == "__main__":
    main()

运行方式:

python audex_probe.py \
  --model REPLACE_WITH_AUDEX_MODEL_ID \
  --audio ./sample.wav \
  --prompt "这段音频里发生了什么?请区分语音内容和背景声音。"

需要改的地方很少,但都很关键:

  • REPLACE_WITH_AUDEX_MODEL_ID:替换为实际模型仓库名。
  • target_sr:按模型要求设置,常见是 16kHz、24kHz 或 48kHz。
  • processor(...) 的参数名:多模态模型经常有自己的输入 schema,不能盲猜。
  • torch_dtype:消费级 GPU 不一定支持 bfloat16,必要时改成 float16 或 CPU float32

更像产品的封装:把音频任务做成一个 HTTP 服务

如果要把这类模型接入内部工具,可以先包一层小服务,统一处理上传、转码、提示词和返回格式。下面是一个可改造的 FastAPI 壳,模型调用部分用占位函数表示,因为 Audex 的真实 processor schema 需要以模型说明为准。

pip install fastapi uvicorn python-multipart librosa soundfile
from tempfile import NamedTemporaryFile
from fastapi import FastAPI, UploadFile, File, Form

app = FastAPI(title="Audio Text Reasoning API")


def run_audio_text_model(audio_path: str, prompt: str) -> dict:
    # 在这里接入 Audex 或同类统一音频-文本模型。
    # 建议返回结构化结果,避免调用方解析一大段自然语言。
    return {
        "summary": "这里替换为模型生成的音频摘要。",
        "speech": "这里替换为识别到的语音内容。",
        "sound_events": ["这里替换为背景声或事件"],
        "prompt_used": prompt,
    }


@app.post("/analyze-audio")
async def analyze_audio(
    file: UploadFile = File(...),
    prompt: str = Form("请总结音频内容,并列出关键声音事件。"),
):
    suffix = ".wav" if file.filename.endswith(".wav") else ".audio"
    with NamedTemporaryFile(delete=True, suffix=suffix) as tmp:
        tmp.write(await file.read())
        tmp.flush()
        result = run_audio_text_model(tmp.name, prompt)
    return result

启动服务:

uvicorn app:app --host 0.0.0.0 --port 8000

调用示例:

curl -X POST "http://localhost:8000/analyze-audio" \
  -F "file=@sample.wav" \
  -F "prompt=请判断这段音频是否包含人声、音乐和异常噪声,并给出简短说明。"

这个封装方式的好处是:前端、数据平台、标注系统不需要知道底层模型到底如何接收音频 token。它们只关心稳定的 HTTP 契约。

适合从哪些场景试起

Audex 这类统一音频-文本模型,不必一上来就替换现有 ASR 或 TTS 系统。更稳妥的切入点是那些“纯转写不够用”的任务:

  • 音频问答:用户上传一段会议、访谈或课堂录音,直接问“谁反对了这个方案”。
  • 声音事件解释:不只判断有没有人声,还描述门铃、敲击、笑声、背景音乐等事件。
  • 多模态质检:结合客服话术、停顿、背景噪声判断通话质量。
  • 音频数据标注:给大批音频生成初始标签,再由人工复核。
  • 播客和长音频分析:把语义内容与声音结构一起纳入摘要。

边界也要讲清楚。统一建模不代表所有任务都比专用模型强。短语音转写、低延迟字幕、固定命令词识别,专用 ASR 或小模型可能更便宜、更稳定。Audex 的价值更可能出现在复杂上下文、开放问题和跨音频-文本推理上。

落地检查表

准备评估 Audex 或同类模型时,可以按这个顺序推进:

  • 先跑 20 到 50 条真实业务音频,不要只用干净 demo。
  • 固定采样率、响度归一化和分段策略,避免输入波动污染评测。
  • 把输出拆成结构化字段,例如 summarytranscripteventsconfidence_notes
  • 和现有 ASR + LLM 流水线并排评测,看它到底在哪些样本上赢。
  • 记录显存、首 token 延迟、总耗时和失败样本,不只看回答质量。
  • 对涉及隐私的音频建立脱敏、访问控制和保留周期。

Audex 的开源说明了一个清晰趋势:音频不会一直停留在“先转文字再理解”的工程范式里。对开发者来说,现在最值得做的不是急着重写生产系统,而是用真实音频把统一音频-文本模型的边界摸清楚。等模型接口、推理框架和部署工具链成熟后,这类架构会自然进入更多语音助手、音频检索和多模态分析产品。


相关推荐