news 2026/9/8 21:35:19

深入解析 Kyutai Speech-To-Text:Transformers 中基于 Mimi 编解码与流式解码的语音识别模型实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入解析 Kyutai Speech-To-Text:Transformers 中基于 Mimi 编解码与流式解码的语音识别模型实战指南

深入解析 Kyutai Speech-To-Text:Transformers 中基于 Mimi 编解码与流式解码的语音识别模型实战指南

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

Kyutai Speech-To-Text(Kyutai STT)是 Kyutai 实验室于 2025 年 6 月正式并入 Hugging Face Transformers 的端到端语音识别模型系列,其核心是把 Mimi 神经音频编解码器 的流式离散音频表征Moshi 风格的自回归语言模型解码器组合成一套统一的双模态 token 体系。本文以 Kyutai Speech-To-Text 官方模型文档为主体,结合仓库内该模型的完整实现,梳理其工作原理、配置参数、特征提取管线与流式generate机制,并给出可直接运行的单条与批量推理示例。

通过本文,你将掌握:如何在 Transformers 中加载并运行kyutai/stt-2.6b-en-trfs等检查点完成英文/法文语音转写;理解音频如何被实时切成 Mimi token 窗口并送入自回归解码器;以及KyutaiSpeechToTextConfigKyutaiSpeechToTextProcessorKyutaiSpeechToTextFeatureExtractorKyutaiSpeechToTextForConditionalGeneration各自承担的角色与关键参数。

模型总览:一套双模态的"音频编解码 + 自回归解码"架构

根据模型文档与源码,Kyutai STT 不是传统的"编码器-注意力解码器"式 ASR,而是一条以音频 token 为第一公民的生成式语音转写链路:

  • 前端编码:Mimi codec 的流式离散化。模型内置一个 Mimi 编解码器(在 HF Transformers 中另有独立模型支持,见 Mimi 文档)。Mimi 以流式方式把 24 kHz 的原始波形编码为离散 token 序列,为自回归解码器提供"逐帧音频表征"。
  • 后端解码:Moshi 风格自回归解码器。解码器是一个类似 Moshi(见 Moshi 文档)的自回归 Transformer,逐帧预测文本 token 与 32 路 RVQ(残差向量量化)码本对应的音频 token。

这种"双模态 token 空间"设计的直接收益是:语音转写可以被建模为与 Moshi 一致的帧级对齐生成——每一帧同时包含文本与音频信息,解码器在帧序列上自回归地前进,从而实现低延迟的流式语音识别,而无需像传统 ASR 那样等待整段音频编码完毕。

官方文档声明当前发布了两档检查点:

  • kyutai/stt-1b-en_fr:约 1B 参数,支持英语与法语双语转写;
  • kyutai/stt-2.6b-en:约 2.6B 参数,专注英文、以最大化转写准确率为目标。

本文所有示例与仓库测试均使用 HF 侧的镜像检查点kyutai/stt-2.6b-en-trfs(见 集成测试 setUp)。该模型于 2025-06-25 由 Eustache Le Bihan 贡献进入 Transformers。

快速上手:单条与批量推理

单条语音转写

模型文档给出的最小推理流程分为五步:加载模型与处理器 → 载入音频 → 预处理 →generate→ 解码。以下代码可直接运行(需要torchdatasetstransformers):

from datasets import Audio, load_dataset from transformers import KyutaiSpeechToTextForConditionalGeneration, KyutaiSpeechToTextProcessor # 1. 加载模型与处理器 model_id = "kyutai/stt-2.6b-en-trfs" processor = KyutaiSpeechToTextProcessor.from_pretrained(model_id) model = KyutaiSpeechToTextForConditionalGeneration.from_pretrained(model_id, device_map="auto") # 2. 加载音频样本(注意:模型期望 24000 Hz 采样率) ds = load_dataset( "hf-internal-testing/librispeech_asr_dummy", "clean", split="validation" ) ds = ds.cast_column("audio", Audio(sampling_rate=24000)) # 3. 准备模型输入 inputs = processor( ds[0]["audio"]["array"], ) inputs.to(model.device) # 4. 推理生成 output_tokens = model.generate(**inputs) # 5. 解码生成的 token print(processor.batch_decode(output_tokens, skip_special_tokens=True))

几点实操细节:

  • 采样率必须为 24000 Hz:处理器内部的特征提取器默认sampling_rate=24000(源码见 feature_extraction_kyutai_speech_to_text.py)。集成测试中加载 LibriSpeech 后同样通过cast_column("audio", Audio(sampling_rate=24000))重采样(见 test_modeling_kyutai_speech_to_text.py)。
  • device_map="auto"依赖accelerate。若在 CPU 上运行可改传device_map="cpu"model.forward的 docstring 示例即采用此写法。
  • 该模型是条件生成任务,inputs通常无需labels,直接generate即可。

批量推理:自动 padding

模型文档同时给出了批量推理版本,核心区别是向处理器传入音频数组列表并开启 padding:

from datasets import Audio, load_dataset from transformers import KyutaiSpeechToTextForConditionalGeneration, KyutaiSpeechToTextProcessor # 1. 加载模型与处理器 model_id = "kyutai/stt-2.6b-en-trfs" processor = KyutaiSpeechToTextProcessor.from_pretrained(model_id) model = KyutaiSpeechToTextForConditionalGeneration.from_pretrained(model_id, device_map="auto") # 2. 加载音频样本 ds = load_dataset( "hf-internal-testing/librispeech_asr_dummy", "clean", split="validation" ) ds = ds.cast_column("audio", Audio(sampling_rate=24000)) # 3. 收集多条音频并做批处理(返回 PyTorch 张量并按最长样本补零) audio_arrays = [ds[i]["audio"]["array"] for i in range(4)] inputs = processor(audio_arrays, return_tensors="pt", padding=True).to(model.device) # 4. 推理生成 output_tokens = model.generate(**inputs) # 5. 逐条解码 decoded_outputs = processor.batch_decode(output_tokens, skip_special_tokens=True) for output in decoded_outputs: print(output)

KyutaiSpeechToTextProcessorKwargs的默认值可以看到(processing_kyutai_speech_to_text.py),该处理器在音频侧默认注入sampling_rate=24000、公共侧默认return_tensors="pt",这正是示例中可以不显式传这两个参数的原因。

双模态 token 空间:解码器到底在预测什么

要正确理解generate的输出,需要先明白模型的输入/输出 token 组织方式。这是全模型最"反直觉"但最核心的设计,源码集中在两个位置:

  1. 可学习嵌入层按码本做偏移求和(modeling 文件)。词表维度定义为vocab_size + num_codebooks * codebook_vocab_size + 1,默认即4001 + 32*2049 + 1。输入序列最后一维是1 + num_codebooks = 33:第 0 列是文本 token,其余 32 列分别对应 Mimi 的 32 个 RVQ 码本。嵌入前,每个非 padding 的音频 token 都会加上自己所属码本的偏移量(offsets[k] = vocab_size + k * codebook_vocab_size),随后在最后一维上求和,得到 (batch, seq, hidden) 的融合向量。
  2. 生成阶段逐帧拼接prepare_inputs_for_generation,modeling 文件)。解码器每个时间步的位置上,input_ids会被构造成(batch, seq, 2)的形态——文本 token 列拼接上当前帧的 32 路音频 token;当某帧使用起始标记时,该帧 32 路音频 token 全部被替换为audio_bos_token_id

用配置文件中的默认 token id 可以更直观地理解这套体系(configuration_kyutai_speech_to_text.py):

字段默认值含义
vocab_size4001文本侧词表大小
codebook_vocab_size2049单个码本的音频 token 词表大小
num_codebooks32RVQ 码本数量(与 Mimi 对齐)
audio_bos_token_id2048音频流起始标记(每个码本内最后一个 id)
audio_pad_token_id69569音频填充标记(等于4001 + 32*2049,同时充当嵌入层padding_idx
bos_token_id48000文本/整体序列 BOS 标记
pad_token_id3文本侧 padding 标记
eos_token_idNone无显式 EOS,靠帧数约束生成长度

值得注意的一个推断:正因为vocab_sizecodebook_vocab_sizenum_codebooks共同决定嵌入表大小和偏移计算,这几个参数在加载官方检查点时不应随意改动,否则 token 语义会发生偏移。

解码器架构与生成机制源码解析

主干为标准的"深度" Transformer 解码器

KyutaiSpeechToTextModel是一个以hidden_size=2048num_hidden_layers=48num_attention_heads=32为主干的自回归解码器(configuration 默认值),并具备以下特征:

  • 分组查询注意力(GQA)num_key_value_heads默认None,在__post_init__中会回退为num_attention_heads(configuration)。
  • 滑窗局部注意力sliding_window=375,配合max_position_embeddings=750,注意力被限制在较短的局部窗口内,从而压低流式生成时的缓存与算力开销。
  • RMSNorm + SiLU 门控 MLP:归一化采用KyutaiSpeechToTextRMSNorm,FFN 维度ffn_dim=11264,激活为hidden_act="silu"的门控结构(KyutaiSpeechToTextGatingMLP)。
  • 旋转位置编码(RoPE)KyutaiSpeechToTextRotaryEmbedding支持rope_parameters中配置的rope_typerope_theta;默认实现遵循原始 RoPE 反频率公式(见 modeling 的 compute_default_rope_parameters)。
  • 多种注意力后端:模型声明_supports_flash_attn_supports_sdpa_supports_flex_attn(modeling),并支持梯度检查点。测试会对比 eager 与 sdpa / flash_attention_2 的输出等价性(见 test 中的注意力实现对比)。
  • fp32 保精度的 codec 分支_keep_in_fp32_modules_strict = ["codec_model"],而解码器主网络可安全地以 fp16/bf16 运行(modeling)。集成测试明确断言加载后codec_model保持 fp32、主干与lm_head为 fp16(test)。

generate是如何把音频"喂"给自回归解码器的

KyutaiSpeechToTextForConditionalGeneration重写了多条生成钩子,构成了下图所示的流式链路:

  1. _prepare_model_inputs(modeling):根据输入波形的实际采样长度,调用 codec 的get_encoded_length推算音频 token 窗口宽度audio_window_size,初始化形状为(batch, audio_window_size, num_codebooks)的全零audio_tokens,记录current_window窗口坐标,并为 Mimi 编解码器准备dynamic cache与各层一维因果卷积的padding cacheKyutaiSpeechToTextConv1dPaddingCache)。也就是说,codec 与解码器都持有独立缓存,是流式解码能够逐段推进的基础。
  2. prepare_inputs_for_generation(modeling):当生成的文本帧推进到当前窗口末尾时,以start * frame_size(start + audio_window_size) * frame_size为界切出新的波形片段,调用codec_model.encode(...)torch.no_grad()下产出该窗口的audio_codes,写回audio_tokens并滑动current_window;随后把"当前帧对应的 32 路音频 token"与文本 token 沿序列最后一维拼接后送入解码器。
  3. generate的自动长度约束(modeling):max_audio_frames = input_values.shape[-1] // codec_config.frame_size。若用户未显式给出max_new_tokens,或给出的值超过了最大音频帧数,会被自动钳制到音频帧总数——因此无需手动指定生成长度,模型天然"听多少、转写多少"

from_pretrained/save_pretrained的重写(modeling)负责把codec_*前缀的生成配置在"模型 GenerationConfig"与"内置 codec 的 GenerationConfig"之间搬运,保证 codec 的流式缓存初始化参数(如sliding_window)在存取后不丢失。

上述流式生成属于实现层面的机制描述;仓库未对 "支持任意长度的实时流式音频输入" 提供文档级承诺,请以实际体验为准。另外测试注释指出:与原始 moshi 代码库相比,QKV 线性层的组织方式差异会使长上下文下的输出逐渐产生偏差,因此集成测试刻意使用较短的输入验证(见 test 注释)。

音频特征提取器:从波形到模型的预处理契约

KyutaiSpeechToTextFeatureExtractor继承自通用的SequenceFeatureExtractor,负责把float32波形整理成模型的input_valuespadding_mask(feature_extraction_kyutai_speech_to_text.py)。其构造参数与语义如下:

参数默认值作用
feature_size1特征维度,1 表示单声道,2 表示立体声
sampling_rate24000音频数字化采样率(Hz)
padding_value0.0填充使用的常数值
chunk_length_sNone若设置,音频会按该秒数切片后再编码
overlapNone相邻 chunk 的重叠比例;用于计算chunk_stride = int((1.0 - overlap) * chunk_length)
audio_delay_seconds0.0在音频之后追加的延迟秒数(右侧补零)
audio_silence_prefix_seconds0.0在音频之前追加的静音秒数(左侧补零)

在调用管线(__call__,见 feature_extraction 源码)内部还有几个容易被忽视但很重要的行为:

  • 强制的采样率校验:若显式传入sampling_rate且与self.sampling_rate不一致,会直接抛出ValueError;若未传则会打印日志警告。建议在调用处理器时始终带上 24 kHz 音频,避免静默错误。
  • 默认开启 paddingpadding=None时被解释为True(补到 batch 内最长样本)。若同时开启truncation会报错。
  • 输入形态约定:单声道要求波形是(num_samples,)的一维数组,立体声要求(2, num_samples);每条样本内部会做转置与 float32 转换,非法维度会抛错。
  • 右侧至少补 1 秒零pad_right = int((audio_delay_seconds + 1.0) * sampling_rate)(feature_extraction),即默认对每条音频右侧补满 24000 个采样点,左侧按audio_silence_prefix_seconds补零,且padding_mask同步扩展。这解释了为何输入会被模型"听到"得比实际语音更长——这是与 Moshi/Mimi 对齐的约定,解码器在这些帧上只产出空白或结束性文本。
  • 分块预处理:当设置了chunk_length_soverlap时,max_length会被规整为 chunk 步长的整数倍边界((nb_step - 1) * chunk_stride + chunk_length),保证切片窗口对齐。

仓库内还提供了chunk_lengthchunk_stride两个动态属性(feature_extraction),它们基于采样率把秒级参数换算为采样点数,并支持在运行时修改chunk_length_s后即时生效——设计意图正是服务于流式/分块场景。

Processor 与 Config:把部件粘合在一起

KyutaiSpeechToTextProcessor

KyutaiSpeechToTextProcessor是标准的ProcessorMixin组合(processing 源码),把一个feature_extractor(音频)与一个tokenizer(文本)绑在一起,__call__时默认把音频侧的采样率设为 24000、统一返回 PyTorch 张量。因此你只需要:

processor = KyutaiSpeechToTextProcessor.from_pretrained(model_id) # 之后 audio 波形会经由 feature_extractor 处理,解码文本则交给内置 tokenizer

batch_decode(..., skip_special_tokens=True)即走 tokenizer 路径把生成的 token id 还原为文本。

KyutaiSpeechToTextConfig

KyutaiSpeechToTextConfig(configuration 源码)是model_type="kyutai_speech_to_text"的配置类,除前文已列的 token 与解码器超参外,还需注意两点:

  • codec_config子配置:声明为sub_configs = {"codec_config": AutoConfig}(configuration)。若未提供,__post_init__会用AutoConfig.for_model("mimi")生成默认的 Mimi 音频编码器配置,并把frame_size等字段回填到模型配置中(configuration)。也就是说,Kyutai STT 在架构层面内嵌了一个完整的 codec 模型,这也是为什么单个类名同时承载了编码与解码两套网络。
  • 架构约束校验@strict装饰的validate_architecture要求ffn_dim必须为偶数,否则抛错(configuration)。

用配置类手工搭一个随机初始化模型的典型写法为:

from transformers import KyutaiSpeechToTextConfig, KyutaiSpeechToTextForConditionalGeneration configuration = KyutaiSpeechToTextConfig() model = KyutaiSpeechToTextForConditionalGeneration(configuration) configuration = model.config # 通过模型访问已补全的配置

代码结构导航:从 modular 到生成文件的工程脉络

该模型在仓库中的源码组织遵循 HF Transformers 的"modular 单源生成"模式:

  • modular_kyutai_speech_to_text.py:真正的维护源文件,所有手写改动应落在这里;
  • modeling_kyutai_speech_to_text.py:由 modular 自动生成的主实现(文件头有显式警告,禁止手改);
  • configuration_kyutai_speech_to_text.py:配置类;
  • feature_extraction_kyutai_speech_to_text.py:音频特征提取器;
  • processing_kyutai_speech_to_text.py:处理器组合;
  • convert_kyutai_speech_to_text_to_hf.py:把原始 moshi/Kyutai 仓库权重(含 Mimi codec 权重)转换为 HF 格式的转换脚本,write_model/write_processor分别产出模型权重与处理器配置。

模型内的关键子模块按职责划分:KyutaiSpeechToTextFlexibleLinear(为每个码本各维护一份线性层权重)、KyutaiSpeechToTextConv1dPaddingCache(因果卷积流式缓存)、KyutaiSpeechToTextEmbeddings(双模态偏移求和嵌入)、KyutaiSpeechToTextAttention/KyutaiSpeechToTextDecoderLayer(带 RoPE 与滑窗的注意力解码层)、KyutaiSpeechToTextModel(主干)、KyutaiSpeechToTextForConditionalGeneration(组合解码器 +lm_head+ 内嵌 codec 的顶层封装,见 modeling 类定义)。

验证与测试依据

想要验证本文描述的行为,可以关注仓库中针对该模型的测试与 fixture:

  • 单元/质量测试文件 tests/models/kyutai_speech_to_text/test_modeling_kyutai_speech_to_text.py:覆盖 fp32 codec + fp16 主干的精度保持、eager/sdpa/flash_attention_2 输出等价性、缓存复用下多次generate的一致性,以及集成测试(slow)中针对 LibriSpeech dummy 样本的精确 token 级输出对齐(见 EXPECTED_TOKENS 断言)。
  • 该模型的配置与权重可从 HF Hub 的kyutai/stt-2.6b-en-trfs检查点直接获取,处理器与模型共用同一个model_id加载。

运行集成测试需slow标记与 GPU 加速器;日常验证请优先使用 CPU/小样本的单元级测试路径。

小结:何时选择 Kyutai STT,以及进一步阅读

总结一下这套方案的关键画像:基于 Mimi 流式离散音频编码 + Moshi 风格双模态自回归解码,输入约定为 24 kHz 单声道波形,处理器默认右侧补 1 秒零、可配置 chunking 与 overlap;解码器在 48 层、32 码本的深度维度上逐帧生成,generate自动以音频帧数封顶生成长度。这套设计让语音转写天然具备流式、低延迟的自回归生成特性,适合希望把 ASR 纳入端到端生成式建模管线的研究与工程场景。

想进一步深入,建议按以下顺序阅读仓库内资料:

  1. 本模型的模型卡片原文档 docs/source/en/model_doc/kyutai_speech_to_text.md;
  2. 前后端依赖的 Mimi 文档 与 Moshi 文档;
  3. 配置、建模、特征提取与转换脚本的源码(路径见上文"代码结构导航"一节);
  4. 测试文件 test_modeling_kyutai_speech_to_text.py,其中有真实检查点的集成验证示例。

最终在代码侧,你只需要记住一条最简用法:

inputs = processor(audio, return_tensors="pt", sampling_rate=24000).to("cuda") tokens = model.generate(**inputs) text = processor.batch_decode(tokens, skip_special_tokens=True)

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 21:33:56

若依前后端分离项目集成数据大屏:地图热力图与3D可视化实践

简介:这是一份基于若依前后端分离框架整合数据大屏与地图能力的完整示例工程,面向需要快速搭建可视化看板、地图检索类功能的Java全栈开发者,可直接嵌入现有若依项目使用,主要适配MySQL数据库。压缩包共655个文件,涵盖…

作者头像 李华
网站建设 2026/9/8 21:33:46

Claude Code 完全指南:从安装配置到进阶玩法与避坑

第一次在终端里敲下 claude 这个命令之前,其实我心里没抱太大期望。毕竟之前也用过不少命令行工具,有的装完就吃灰,有的光配置就折腾一下午。但 Claude Code 属于那种“打开方式一换,效率完全不一样”的工具。它不是网页里那种一…

作者头像 李华
网站建设 2026/9/8 21:31:50

IAR Embedded Workbench原生Linux版深度解析

1. 项目概述:IAR平台这次真把“跨平台IDE”做实了 最近在嵌入式开发圈里,不少老同事发来截图问:“IAR真出Linux版IDE了?不是插件、不是WSL套壳、不是远程桌面连Windows主机,是原生Linux桌面应用?”——答案…

作者头像 李华
网站建设 2026/9/8 21:31:03

UART帧传输时间精确计算:从115200波特率到7位模式

1. 这不是“背公式”问题,而是理解UART物理层本质的起点你手头正调试一块STM32开发板,串口打印突然卡顿;或者在用FT231X芯片做USB转UART桥接时,发现上位机接收数据错乱;又或者在设计一个低功耗传感器节点,需…

作者头像 李华
网站建设 2026/9/8 21:31:01

Ubuntu 20.04无人机开发环境搭建:ROS+PX4仿真避坑指南

从入门到能跑仿真:Ubuntu 20.04 无人机软件开发环境的搭建与避坑不管你是打算做 PX4/ArduPilot 二次开发,还是想在机载电脑上跑 ROS 做视觉避障,只要跨进无人机软件开发这扇门,第一个绕不开的环境就是Ubuntu 20.04。我见过太多人卡…

作者头像 李华