设想你走进一家忙碌的老字号川菜馆。客人陆续落座,点菜声、跑堂声、锅铲声混成一片。服务员把顾客口中的“宫保鸡丁”“鱼香肉丝”飞快记下,传到后厨;大厨对照菜谱核对食材和火候,再按“备料—热锅—下锅—装盘”的顺序出菜;后厨经理统筹全局,保证每桌的菜最终准确上桌。这套流程看似繁琐,却撑起了几代餐厅的经营。 语音识别在深度学习统治之前,也恰好是这副模样。声音波形先被“服务员”提炼成MFCC特征,交给名叫GMM的“菜谱核对员”判断每个片段像哪个音素,再用名叫HMM的“上菜流程员”把音素按时间顺序串成语音,最后由解码器结合语言习惯输出一整句文字。后来,一位叫DNN的“大师傅”加入后厨,不再逐页翻菜谱,而是靠海量实战积累练出直觉,让识别准确率大幅提升,但HMM这位“流程员”依然没有离开。GMM-HMM与DNN-HMM,正是语音识别“前世”里最重要的两套前后相继的班底。
理解传统ASR的“骨架”是深入现代语音识别与维护遗留系统的必修课,能帮你从技术演进角度理解端到端模型的诸多设计取舍。
可视化演示
展示多序列比对(MSA)的渐进式对齐过程,以及共进化信号如何帮助AlphaFold预测蛋白质三维结构。
本节配有交互动效(进入视口后自动加载,约 3KB)。
MSA多序列比对 渐进式:先两两比对,再逐步合并 插入空位:对齐保守区域 共进化:协同变异揭示空间邻近 MSA → Coevolution → 3D Structure MSA是AlphaFold预测蛋白质结构的关键输入
语音识别概述
老后厨的一天,从顾客开口“宫保鸡丁不要花生”开始。声音传到耳边,后厨关注的不是情绪的起伏,而是那串必须被执行的明确指令。语音识别(ASR,Automatic Speech Recognition)干的正是这种活:在机器里把“声音”翻译成“文字”。传统ASR的流程在几十年前就定下了:录音采样→分帧→提取特征→声学模型打分→语言模型排候选→解码器输出文本。这好比服务员记单(特征提取)、厨师认料(声学模型)、经理统筹上菜(解码)。
从数学上看,ASR的核心目标是在所有文字候选中找出后验概率最大的那一个。这个目标把一个复杂的声音理解问题,拆成了可独立优化的子问题:声学特征、声学模型、语言模型和搜索算法。
这套“点菜、认料、出菜”的思路,几乎定义了整个传统语音识别时代。GMM-HMM和DNN-HMM,正是这个流程里“声学模型”的两种具体实现方式。理解了总目标,后面的每种模型都只是在回答同一个问题:P(O|W) 该怎么算才更准。
- 观测序列 O经过特征提取后的一连串特征向量,可以看作服务员记下的一叠点菜单子。
- 文本序列 W我们要输出的汉字或词语序列,也就是后厨最后端上桌的那道菜。
- 后验概率 P(W\|O)在已知声音特征 O 时,文字 W 成立的概率。用贝叶斯公式可拆成语言模型 P(W) 与声学似然 P(O\|W) 的乘积。
- argmax 最优选择从所有候选文本里挑出得分最高的那一个。实际系统用维特比等动态规划算法高效求解。
声学特征提取
服务员要把顾客的一段话记成几条要点,而不是把整段录音原封不动地传给后厨。语音特征提取做的也是类似的事:把连续波形切成20~30毫秒的小帧,并为每一帧算出一串最能反映发音差异的数字。为什么可以切帧?因为语音在极短时间里是相对平稳的,这一假设叫短时平稳性,相当于后厨相信“一秒钟内的火候不会剧变”。
最经典的特征是MFCC(梅尔频率倒谱系数)。它先用梅尔滤波器组模拟人耳对频率的非线性感知,再取对数压缩动态范围,最后做离散余弦变换,把高维且彼此相关的频谱能量压缩成低维、去相关的特征向量。
特征提取是整套系统的“前台接待”:它决定了后厨看到的是清爽的订单还是混乱的流水账。MFCC 虽然丢掉了相位等细节,却抓住了人耳最敏感的声音轮廓,这正是后厨最需要的“菜谱线索”。
- 滤波器数量 M梅尔滤波器组的通道数,通常取24或40,就像服务员用来记录订单的“分栏数”。
- 滤波器能量 S_m第 m 个梅尔滤波器输出的能量,表示这一帧声音在那个频率区间的分量大小。
- 取对数压缩把人耳对音量的“幂压缩”感觉加进来,就像区分微辣、中辣、特辣,而不是线性记录辣椒颗数。
- 余弦变换核cos 项把高度相关的对数能量去相关,便于用少量系数承载主要声学信息。
- MFCC 系数 c_t对所有滤波器输出加权求和,得到第 t 帧的第 t 个倒谱系数,最终拼成该帧的特征向量。
GMM建模
大厨判断食材,靠的是一套“标准形态”:青椒的形状、色泽、手感可能各不相同,但总体服从某些分布。GMM(高斯混合模型)就是这个思路——用多个高斯分布加权组合,为每个音素训练出一个特征空间里的“势力范围”。如果一个音素的发音只有一种典型形态,一个高斯就够;可真实世界里同一个音素会因口音、性别、语速而呈现多个聚集中心,所以需要多个高斯叠加。
GMM 不直接回答“这是哪个音素”,而是回答“当前特征在这个音素模型下有多像”,输出一个概率密度值。训练时用 EM 算法,交替执行 E 步(计算每个高斯分量的后验责任度)和 M 步(重新估计权重、均值、协方差),直到模型收敛。
在 GMM-HMM 系统中,GMM 就像那个只盯着一片食材的“认菜大厨”。它不负责菜的顺序、不负责上菜时间,只负责一件事:这块食材更像哪种备料。而正是这种“分内之事”的专注,让它能精确刻画每个音素的声学特征分布。
- 输入特征向量 xx 是某一帧的 MFCC 向量,相当于后厨手里一片待辨认的食材。
- 分量个数 KK 表示这个音素模型由多少个高斯“子模板”组成。
- 混合权重 w_k第 k 个子模板占的比重,所有权重之和为 1。
- 高斯密度函数多维钟形函数,μ_k 决定分布中心,Σ_k 决定椭圆形状和朝向。
- 加权求和把 K 个钟形曲线按权重叠加,得到这个音素模型的概率密度。
HMM建模
食材认完后,后厨还要按顺序做菜:先备料、再热锅,最后装盘。语音也有严格的时序——先发哪个音、后发哪个音,顺序错了意思就全变了。HMM(隐马尔可夫模型)负责的正是这种“上菜节奏”:用一组隐藏状态表示音素的推进过程,用转移概率刻画状态之间的先后依赖。
为什么叫“隐”马尔可夫?因为状态本身看不见,我们只能通过每一帧的特征(观测)去推测当前处于哪个状态。一段语音被切成几十上百帧,一个音素往往跨越十几帧,并且内部有“起始、中间、收尾”的变化,HMM 正是为这种多帧时序结构而生的。
在 HMM 看来,语音识别就是一场有先后顺序的“上菜流程”。做完“切菜”状态,下一状态是“下锅”的概率很高,是“洗碗”的概率极低——这种时序约束,正是 HMM 给整个系统注入的“肌肉记忆”。
- 模型参数 λHMM 的参数集合,包含初始概率 π、状态转移矩阵 A 和发射概率 B。
- 隐藏状态路径 Q每一帧对应的状态序列,比如“起始→中间→末尾”。
- 初始概率 π第一帧落在某个状态上的概率,相当于后厨开工后第一道工序从哪一步开始。
- 状态转移概率 a从状态 q_{t-1} 转移到 q_t 的概率,刻画音素内部推进的快慢。
- 发射概率 b当前状态 q_t 产生观测帧 o_t 的概率,由声学模型给出。
GMM-HMM混合架构
一个负责“像不像”,一个负责“先后来”,两者结合就构成经典声学模型。在 GMM-HMM 混合架构里,每个 HMM 状态都配有一个专属 GMM:HMM 决定状态如何随时间跳转,GMM 负责计算该状态在当前帧上的发射概率。二者一配合,既有了精细的声学判别力,又有了流畅的时序建模能力。
实际工程中,直接用单音素建模不够精确,因为同一个音素的发音会受前后音素影响,这叫协同发音。于是系统引入上下文相关的三音素建模,把“左音素+中心音素+右音素”作为建模单元,再通过决策树聚类共享参数,把成千上万个三音素状态压缩到可训练的规模。
GMM-HMM 的训练用前后向算法(Baum-Welch)迭代完成:先按当前“菜谱”给数据打分,再根据打分结果反向修正“菜谱”里的每个参数,如此反复。就像后厨根据客人反馈不断微调菜谱配比,直到整本菜谱稳定下来。
- 状态索引 j上下文相关音素中的某个 HMM 状态,比如“b-a-d”这个三音素的中间子状态。
- 当前帧 o_tt 时刻的 MFCC 特征向量,是 GMM 的输入。
- 混合权重 w_{jk}第 j 个 HMM 状态里第 k 个高斯分量的权重。
- 高斯参数 μ 和 Σ第 j 状态第 k 个高斯的均值和协方差,决定该子模板的声学“长相”。
- 发射概率 b_j(o_t)GMM 的概率密度直接作为 HMM 的发射概率,供前向算法和维特比解码使用。
DNN-HMM演进
2012年前后,后厨迎来一位“大师傅”——深度神经网络。他不再逐页翻纸质菜谱,而是从几万道菜里自己总结规律,一眼就能看出“这道菜大概是回锅肉”。DNN-HMM 用 DNN 替换 GMM 作为发射概率模型,HMM 的时序框架则原地保留,形成新一代混合架构。
DNN 的输入常取当前帧左右各若干帧拼接而成的上下文特征,输出则是每个 HMM 状态的后验概率。相比 GMM 只能刻画浅层的特征分布,DNN 通过多层非线性变换逐层抽象原始特征,对声学可变性的建模能力明显更强。把后验除以状态先验,就能转换成 HMM 所需的发射似然。
DNN-HMM 更像是“大师傅带流程”:大师傅负责精准判菜,HMM 这位老流程员依然负责出菜顺序。识别率的跃升,来自大师傅“看得多、认得准”——但对时序的尊重,使得 HMM 在混合架构中依然不可替代。
- 后验概率输出DNN 最后一层用 softmax 输出状态 j 在特征 o_t 下的后验概率。
- 状态先验训练语料中状态 j 出现的频率统计,相当于后厨里一道菜被点的“基础人气”。
- 后验转似然把后验除以先验,得到 HMM 发射似然,抵消不同状态出现频率不均衡带来的偏差。
解码与瓶颈
模型训练完成后,还需要最后一道环节:把声学模型和语言模型的分数综合起来,搜索出最可能的整句文字。这道工序就是解码,而解码器的主角是维特比算法。它用动态规划维护每一帧到达每个状态的最优路径分数,并记录回溯指针,最后从终点倒推回完整路径。语言模型(常用 N-gram)则在解码中告诉系统哪些词更常连在一起,避免选出字面合理但不符合语言习惯的句子。
尽管 GMM-HMM 与 DNN-HMM 在各自时代称霸,但这套架构也面临瓶颈:声学模型、语言模型、发音词典分别训练和调优,流程繁重;标注需要帧级对齐,成本高;各组件优化目标不一致,难以全局最优。进入大数据与强算力时代后,端到端模型直接输入特征、输出文本,把整条“后厨流水线”压成一个整体网络,逐步成为新主流。不过,老后厨那套“先记单、再判菜、按序出菜”的逻辑,依然影响着今天的每一间自动化厨房。
---
- 最优部分路径分数 δ_t(j)到 t 时刻为止,以状态 j 结束的最佳路径累计得分。
- 遍历前序状态取最大从上一时刻所有状态 i 出发,加上转移概率 a_{ij},取最大值。
- 乘发射概率把当前帧在状态 j 下的声学似然乘进去,完成对本帧的打分。
- 回溯指针记录取得最大值的前序状态 i,解码结束后从最后时刻依次倒推,恢复整个状态路径。
AI 应用场景
遗留IVR客服系统维护与升级
阶段:模型维护与迁移
解决的问题:银行、运营商呼叫中心仍有大量基于 GMM-HMM 或 DNN-HMM 构建的语音导航系统。这类系统依赖稳定的帧级解码和规则化流程,直接替换成端到端模型成本高风险大。技术人员需要能阅读模型输出日志,快速定位转写错误来自声学模型还是语言模型。
具体案例:某银行客服热线的语音菜单中,用户说“查余额”被系统转写为“查鱼额”。维护工程师查看 HMM 状态路径后发现“鱼”音素的 GMM 发射概率异常,进一步定位到是方言口音数据不足,于是用新语料重训练声学模型,问题修复。
端到端训练数据对齐
阶段:数据准备
解决的问题:训练 Whisper 等端到端模型需要大量“语音-文本”对齐信息,人工标注帧级边界成本高昂。DNN-HMM 的强制对齐能力可以把语音自动切分到帧级状态,生成高质量训练标签。
具体案例:某团队要为中文方言微调端到端模型,先使用 DNN-HMM 对 1 万小时语料做强制对齐,得到帧级音素状态标签,再用这些标签清洗数据、过滤错配样本,最终微调出的模型准确率显著提升。
流式与低资源语音识别
阶段:在线解码
解决的问题:手机和 IoT 设备上,超大端到端模型延迟高、内存占用大,不适合本地实时识别。轻量 DNN-HMM 架构可以用较小模型完成流式解码,即使断网也能工作。
具体案例:智能音箱的本地唤醒词与命令词识别,用轻量 DNN-HMM 在芯片上完成“打开空调”“播放音乐”等指令的实时识别,响应时间控制在毫秒级。
Python 演示
import numpy as np class GMM: """高斯混合模型, 模拟语音识别中的音素声学模型.""" def __init__(self, n_comp=1): self.n_comp = n_comp self.w = np.ones(n_comp) / n_comp self.mu = np.random.randn(n_comp, 2) * 0.5 self.cov = np.tile(np.eye(2), (n_comp, 1, 1)) def _gauss(self, x, k): d = x - self.mu[k] inv = np.linalg.inv(self.cov[k]) det = np.linalg.det(self.cov[k]) return np.exp(-0.5 * d @ inv @ d) / np.sqrt((2 * np.pi) ** 2 * det) def pdf(self, x): return sum(self.w[k] * self._gauss(x, k) for k in range(self.n_comp)) def fit(self, X, epochs=20): N = len(X) for _ in range(epochs): gamma = np.zeros((N, self.n_comp)) for i, x in enumerate(X): for k in range(self.n_comp): gamma[i, k] = self.w[k] * self._gauss(x, k) / max(self.pdf(x), 1e-12) Nk = gamma.sum(axis=0) self.w = Nk / N self.mu = (gamma.T @ X) / Nk[:, None] for k in range(self.n_comp): diff = X - self.mu[k] self.cov[k] = (gamma[:, k, None] * diff).T @ diff / Nk[k] def viterbi(trans, init, emit): """维特比解码: 在HMM中找出最可能的隐状态路径.""" T, S = emit.shape V = np.full((T, S), -np.inf) B = np.zeros((T, S), dtype=int) V[0] = np.log(init + 1e-12) + np.log(emit[0] + 1e-12) for t in range(1, T): for j in range(S): cand = V[t - 1] + np.log(trans[:, j] + 1e-12) + np.log(emit[t, j] + 1e-12) V[t, j] = cand.max() B[t, j] = cand.argmax() path = [int(V[-1].argmax())] for t in range(T - 1, 0, -1): path.append(int(B[t, path[-1]])) return path[::-1] if __name__ == "__main__": rng = np.random.RandomState(0) X_a = np.vstack([rng.randn(40, 2) + [-2, -1], rng.randn(40, 2) + [-2, 1]]) X_i = np.vstack([rng.randn(40, 2) + [2, -1], rng.randn(40, 2) + [2, 1]]) gmm_a = GMM(2) gmm_i = GMM(2) gmm_a.fit(X_a) gmm_i.fit(X_i) frames = np.vstack([X_a[:8], X_i[:8], X_a[:4]]) emit = np.stack([[gmm_a.pdf(x) for x in frames], [gmm_i.pdf(x) for x in frames]], axis=1) trans = np.array([[0.9, 0.1], [0.2, 0.8]]) init = np.array([0.6, 0.4]) path = viterbi(trans, init, emit) print("解码状态序列:", path) print("期望状态序列:", [0] * 8 + [1] * 8 + [0] * 4)
gamma[i, k] = self.w[k] * self._gauss(x, k) / max(self.pdf(x), 1e-12)E 步:计算第 i 个样本对第 k 个高斯分量的后验责任度,相当于判断这片食材更该归哪个子模板。self.w = Nk / NM 步:更新各分量权重,相当于统计各子模板被使用的频率。self.mu = (gamma.T @ X) / Nk[:, None]M 步:按责任度加权平均,重估每个高斯分量的中心位置。self.cov[k] = (gamma[:, k, None] * diff).T @ diff / Nk[k]M 步:重估协方差,调整子模板的扁圆形状。V[0] = np.log(init + 1e-12) + np.log(emit[0] + 1e-12)维特比初始化:计算第一帧到达各状态的初始路径分数。cand = V[t - 1] + np.log(trans[:, j] + 1e-12) + np.log(emit[t, j] + 1e-12)维特比递推:把前一帧最优分数、转移概率和当前帧发射概率相加,取最大值。
常见误区
误区GMM-HMM 里,GMM 肯定负责把声音按时间顺序串起来,HMM 负责分类音素,这样分工才合理吧?
正解不是。GMM 只对单个帧特征做密度估计,回答“这一帧像哪个状态”;真正对时间顺序负责的是 HMM。用后厨比喻:GMM 是只盯着一片食材下判断的认菜大厨,HMM 则是规定“先备料、后炒菜”的流程监督员。混淆二者,会遇到“明明 GMM 已经分对了类,识别还是乱序”的困惑。
为何常见:HMM 名字里有“时间序列”,GMM 名字里有“模型”,初学者容易按字面分配职责,而缺少对“发射概率 vs 状态转移”的清晰区分。
误区HMM 里的隐藏状态不就是声母韵母或者汉字吗?反正模型最终输出词序列。
正解不是。传统 ASR 的 HMM 状态通常是比音素更细的“亚音素状态”,且最常用的是三音素上下文相关状态。上下文相关是因为“ba”“da”等发音受前后音素影响。HMM 状态本质是声学层建模单元,与语义层的汉字并不直接对应,中间还隔着音素、词典和语言模型。
为何常见:教材常把 HMM 用于词性标注等高层任务,导致初学者把隐状态与词或字联系在一起,忽略了 ASR 中它是声学状态集合。
误区DNN 这么强,应该把 GMM 和 HMM 都替换掉,DNN-HMM 就是全神经网络模型。
正解DNN 只替换了 GMM 作为发射概率模型,HMM 的时序结构完整保留。公式 b_j(o_t)=P(s_j|o_t)/P(s_j) 中,状态 j 仍是 HMM 状态,转移概率 a_ij 仍由 HMM 提供。真正“全端到端”的是后来的 CTC、注意力等模型。所谓“混合架构”,正是新旧模型的协同。
为何常见:深度学习宣传中“取代”叙事太多,加上 DNN 名称醒目,容易让人忽略 HMM 在时序上的不可替代性。
误区既然是特征提取,那就应该尽量保留全部信息,MFCC 把声音数据压缩了,会损失很多信息吧?
正解MFCC 有意识地舍弃了相位等对识别收益不大的信息,保留的是模拟人耳听觉的谱包络。这种“有损压缩”是当年计算资源和模型结构限制下的合理折中。深度学习时代,谱图甚至原始波形也能直接建模,但这不意味着 MFCC 是“错误”的——它在特定条件下依然高效。
为何常见:直觉上“信息越多越好”,忽略了人耳与识别系统真正需要的是判别性信息,而非全部声学细节。
误区Whisper 等端到端模型识别率那么高,GMM-HMM/DNN-HMM 已经过时,没必要再学了。
正解一批生产系统、低资源语言和流式识别场景仍在沿用混合架构。更重要的是,理解传统 ASR 能帮你解释现代模型的失败模式,比如时长对齐错误、语言模型融合失效等。技术演进是渐进式的,传统架构里每个组件解决的问题并没有消失。
为何常见:技术媒体偏爱“颠覆”叙事,而真实系统的迁移成本、数据限制和延迟要求,往往让传统架构在很长一段时间内继续服役。
面试题
Q1. 在GMM-HMM语音识别中,哪个组件负责描述“音素状态的声学特征分布”?
- A.语言模型计分
- B.GMM声学概率← 正确答案
- C.HMM状态转移
- D.维特比解码算法
答案:B。GMM 是声学模型,负责计算某一帧特征属于某状态的概率密度;HMM 负责时序转移,语言模型负责词序列打分,维特比负责解码搜索。GMM 就像“认菜大厨”,只看当下食材像不像某状态的菜。
Q2. 关于HMM在语音识别中的作用,以下说法正确的是?
- A.建模相邻帧的时间顺序← 正确答案
- B.用转移概率约束状态跳转← 正确答案
- C.把文本直接转写成音素
- D.用发射概率关联声学特征← 正确答案
答案:ABD。HMM 通过状态转移概率建模时序推进,通过发射概率连接声学特征;文本转写音素不是 HMM 的职责,而是词典和语言模型的事。
Q3. DNN-HMM相比GMM-HMM最主要的改进是?
- A.用DNN全部替换HMM
- B.用DNN替代GMM算发射← 正确答案
- C.用DNN做语言模型
- D.用DNN做特征提取器
答案:B。DNN-HMM 中 DNN 只替换 GMM 来估计发射概率,HMM 仍负责时序转移。DNN 得益于深层非线性变换和多帧上下文,声学建模能力远超 GMM。
Q4. MFCC特征提取中,离散余弦变换(DCT)的主要作用是?
- A.将时域信号转为频域
- B.消除声源的周期谐波
- C.对梅尔对数谱去相关压缩← 正确答案
- D.把宽频语音划分成子带
答案:C。时域转频域是傅里叶变换的工作,梅尔滤波已经完成了子带划分,DCT 负责对高度相关的梅尔对数能量做去相关压缩,让少量系数就能表达主要声学信息。
Q5. 维特比算法相比“全路径求和”的主要优势是什么?
- A.用动态规划剪枝重复计算← 正确答案
- B.只保留每个时刻最优路径← 正确答案
- C.穷举所有状态序列组合
- D.用回溯指针恢复完整路径← 正确答案
答案:ABD。维特比用动态规划维护每个时刻每个状态的最优路径,避免指数级穷举;回溯指针在解码结束时倒推完整路径。它不求所有路径概率和,只求最优路径,因此高效。
Q6. 在贝叶斯决策公式中,P(O|W)通常称为?
- A.先验概率分布
- B.声学似然概率← 正确答案
- C.词的先验概率
- D.语言模型分数
答案:B。P(O|W) 是在给定文本 W 的条件下观测到语音特征 O 的似然,由声学模型提供。先验 P(W) 才是语言模型。两者相乘再归一化得到后验 P(W|O)。
Q7. 关于发射概率 b_j(o_t) 的作用,下列说法正确的是?
- A.反映状态j生成帧ot的概率← 正确答案
- B.在GMM-HMM中由GMM负责← 正确答案
- C.由语言模型直接给出
- D.描述状态间的跳转
答案:AB。发射概率连接 HMM 状态与观测特征,在 GMM-HMM 中由 GMM 计算;语言模型负责词序列得分,转移概率才描述状态跳转。
Q8. 训练GMM时,EM算法的E步骤完成的任务是?
- A.用梯度下降更新参数
- B.计算隐变量的后验概率← 正确答案
- C.重新估计全部模型参数
- D.用词典查找对应文本
答案:B。E 步计算每个样本属于每个高斯分量的后验责任度,M 步再利用这些责任度重估权重、均值和协方差。没有 E 步的“软分配”,就无法可靠地更新参数。
Q9. 三音素建模解决的核心问题是?
- A.区分同音异形字
- B.建模协同发音影响← 正确答案
- C.大幅压缩特征维度
- D.降低语言模型复杂度
答案:B。同一个音素在不同前后语境中发音不同,三音素模型以“左音素+中心音素+右音素”为单元,能捕捉协同发音影响。汉字区分和特征压缩不是它的目标。
Q10. 为什么DNN-HMM能比GMM-HMM取得更高识别率?
- A.拼接相邻帧来刻画上下文← 正确答案
- B.深层非线性特征映射更强← 正确答案
- C.直接替换掉整体语言模型
- D.输出后验供HMM发射使用← 正确答案
答案:ABD。DNN 输入多帧拼接特征,能利用动态上下文;多层非线性结构学到的特征表示比 GMM 的浅层分布更丰富;输出后验除以先验后作为 HMM 发射概率。它并没有替换语言模型,语言模型仍在解码阶段发挥作用。