小林第一天上班就被派去做同传速记:领导在台上讲话,他要在公屏上实时打出翻译字幕。他一开始热血上头,贴着发言人的语速逐词翻译——结果刚译出“昨天”两个字,领导后半句冒出一句“我们并没有亏钱”,小林已经来不及改了。老翻译师傅老周看了看屏幕,只说了八个字:“先听 k 个词,再开口写。”这句话,正是同传机器翻译领域经典策略 wait-k 的全部精髓:模型不急着翻译,它先老老实实读入 k 个源语言词;之后每读到新词,才往前多写一个目标语言词。k 选得小,字幕跟得快,但容易听岔了没法回头;k 选得大,翻译稳了,但观众等得心焦。读懂这个“落后 k 个词”的读写节奏,你就明白:同传里快与稳之间的那份精妙平衡,原来可以被一个整数精确地调节。
掌握 wait-k 的读写逻辑与 k 值调优方法,你就拿到了实时翻译系统的“延迟-质量”调音台——这正是语音同传、直播字幕、流式大模型等场景中算法工程师的核心竞争力。
目录
可视化演示
动态演示同声传译中的wait-k策略的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
同声传译中的wait-k策略:wait wait-k策略原理与读写机制 k值选择与延迟质量权衡分析 核心机制可视化 同声传译中的wait-k策略整体架构与关键组件
读写机制:落后 k 个词的“慢半拍”心法
小林第二次上场,牢牢记住“先听 k 个词”。领导开口说“我 昨天 看了 一部 电影”,前三个词“我、昨天、看了”刚落进耳朵,小林就开始写第一句译文;领导每多说一个词,小林就多写一个词,手里的笔永远比领导慢三拍。头一次,他既没抢话,也没落词。
机器翻译里的 wait-k 就是把这种“慢半拍”量化成一条读写规则:模型要生成第 t 个目标语言词时,只允许看到源语言句子的前 min(t+k-1, N) 个词。这里的“读”指编码器实际参与注意力计算的源前缀范围,“写”指解码器吐出的第 t 个目标词,k 就是那份“余量”。
1. 目标词序号 t:t 表示当前写到第几个目标语言词,从 1 开始计数。
2. 已读数 t+k-1:写到第 t 个目标词时,已经读了前 t+k-1 个源词,这就是“落后 k 个词”的数学形态。
3. 封顶函数 min:当 t+k-1 超出源句总长 N 时,只读到 N 为止,之后不再等新词、专心补完剩余译文。
这套机制由三个齿轮协同转动。第一是前缀读取:编码器每一步都对“目前已经到达”的源词做注意力,绝不偷看未来的词;第二是逐词写入:解码器每产生一个目标词,才允许读入一个新源词,形成“读一写一”的节奏;第三是边界封顶:源句一旦结束,min 函数把读入数钉在 N,模型转入纯生成阶段把尾巴补完。注意,读入的永远是“前缀”而不是任意位置的词——这保证了模型只使用刚才真听到的内容,这正是流式系统能落地的根基。
小林后来发现,这条规则像极了老周教他的笔记习惯:写下一行之前,先确认上一行的意思已经完整;笔永远落后耳朵几个词,但心里装着全部已听的内容。慢半拍,不是迟钝,而是给理解留出余量。
k 值权衡:等几个词才合适?
小林开始试不同的 k。k=1 时他贴着领导说,字幕几乎同步,可领导语序一倒装就翻车;k=8 时他翻译得又准又润,但观众盯着屏幕干等,短句还好,长句等得人心焦。到底该等几个词?
这背后是“延迟—质量”的跷跷板。衡量延迟最常用的刻度叫平均滞后(Average Lagging, AL):对每个目标词,记录它在模型已经读到第 g_t 个源词时产出,再减去它真正对应的源词位置 c_t,把所有差值平均起来,就得到了整句话的平均滞后。
1. 目标词个数 τ:把源句翻译完后一共产生了多少个目标词,作为平均的分母。
2. g_t:已读源词数:写第 t 个目标词那一刻,模型已经读到的源词总数。
3. c_t:对齐位置:第 t 个目标词在源句里真正对应的那个词的序号,由注意力或对齐模型给出。
4. 求平均:逐词求差值后累加再除以 τ,就得到平均滞后 AL,单位是“源词个数”。
AL 越大,观众等得越久;而翻译质量分 BLEU 通常随 k 增大而升高,但涨到某个值后就进入平台期——多等的词不再带来新信息。原始 wait-k 论文在英德、德英等语言对上发现,k=3 到 5 是常见的甜点区;中文到英文这类词序差异大的方向,k 往往还要再大一点。语速也参与折算:汉语发言大约每秒 4 到 5 个词,k=4 意味着约 0.8 到 1 秒的固定滞后,正好落在人眼读字幕的舒适区间。
老周最后送给小林一张选 k 口诀:语序差异大,k 往大调;观众性子急,k 往小调;语速偏快时,同样词数占用的时间更短,k 可以适当放宽。小林把它记在笔记本上——k 不是拍脑袋定的,而是拿“观众愿意等多久”换算出“能容忍几个词”。
策略对比:整句、wait-k 与自适应
小林借着观摩的机会偷偷看了另外两位速记员的风格。A 师傅整句听完才落笔,字幕又准又完整,但一句话的延迟几乎等于整句时长;B 师傅“看菜下碟”,简单句秒翻、长难句等一等,灵活是真灵活,可经常手忙脚乱;老周的 wait-k 最“老实”:固定落后 k 个词,雷打不动。
这三种风格对应三类同传策略。整句翻译(full-sentence, k=N)让编码器读完整个源句才开始解码,质量上限最高,但首词延迟约等于整句时长,对同传场景几乎不可用;自适应策略(adaptive,如 MMA 类方法)让模型自己学习“何时再读、何时开写”的门控,延迟随句子难度起伏,上限更优但工程复杂、训练更重;wait-k 胜在简单可预期:延迟上界是解析的、可控的。
1. 每词时长 Δ:发言人平均每说出一个源词需要的时间,比如约 0.2 秒。
2. wait-k 的首词延迟:要等齐 k 个源词才能写出第一个目标词,观众先等 k×Δ 秒。
3. 整句的首词延迟:full-sentence 要等齐整句 N 个词才开始翻译,观众先等 N×Δ 秒。
量化之后差异一目了然:整句延迟通常比 wait-k 大一个量级;自适应策略虽然灵活,延迟却像心电图一样忽高忽低。工程上,wait-k 的“确定性”是巨大优点——延迟可以写进 SLA 承诺、可以在压测时精确推算、出了问题可以复现;B 师傅那种机灵策略,反而让产品团队不敢接需求。不同场景的适用性也因此分明:字幕交互爱 wait-k,机器翻译评测里整句仍吃香,而自适应更适合长句居多的正式会议。
小林最终跟了老周。当直播间的需求是“延迟必须 1 秒内”时,wait-k 拍一个 k 就能给出承诺,而“随机应变”在工程合同面前反而成了风险。简单、可预期,本身就是一种战斗力。
模型训练:一个模型怎么学会所有 k?
小林的疑问来了:总不能每个 k 都专门练一个我吧?老周的回答出人意料:练的时候随机抽一个 k 来练——今天练 k=2 的语速,明天练 k=7 的语速,练成一个“给哪个 k 都能上”的万能译员。
这正是 Universal wait-k 的思路。第一阶段用普通完整句语料做预训练初始化,让模型先具备基本的翻译能力;第二阶段进入“前缀训练”:每个训练步随机采样一个 k(1 到 K 之间均匀抽取),按 wait-k 规则把样本截断——编码器只看源前缀 x_{≤min(t+k-1,N)},解码器只看目标前缀 y_{<t},然后预测下一个目标词。
1. 随机采样 k:每个训练步先从 1 到 K 均匀地抽取一个 k,作为本步的滞后档位。
2. 条件概率:给定目标前缀 y_{<t} 和“读到 min(t+k-1,N)”的源前缀,模型预测第 t 个目标词的概率。
3. 负对数似然求和:对句中每个目标词的预测损失求和,这是标准的交叉熵损失。
4. 期望外层:对所有可能的 k 取期望,强迫同一个模型把所有滞后档位都练到。
还有一种更早的技巧叫 wait-k polish:先在大 k(接近整句)上把模型训稳,再让 k 从大到小逐渐收窄,像把橡皮筋慢慢拉紧,最终压到目标小 k。“前缀截断”是这两种方法的共同灵魂:训练时模型看到的输入形态,必须和推理时一模一样——边读边写的形态如果只在测试时出现,模型一上生产线就会露馅。Universal 方式最终只留一个模型,部署后 k 可以按业务动态切换,不用重新训练,这也是它成为主流的原因。
小林恍然大悟:练口译要同时适应语速快和语速慢的客户,模型见的 k 越多,上场越从容;而前缀截断,就是把排练时的桌椅摆放调成和正式演出完全一致。
流式解码:缓存复用与不可回溯
真实场景里,源词不是一个不漏同时到齐的——领导说一句,麦克风传一个词。小林发现,如果每来一个新词就把整段话重新抄一遍,手早就断了。正确做法是:新词来了只记新的,旧笔记原封不动。
工程上对应“增量编码”与 KV 缓存复用。增量编码指新源词到达时,只把新词追加进编码器输入,复用之前算好的注意力 Key/Value 缓存,而不是把整个前缀重新前向计算一遍。全量重算的工作量像 1+2+……+T 的阶梯,一次比一次高;缓存复用后,工作量变成一条平缓上升的直线。
1. 全量重算的阶梯:每来一个新词就把整个前缀重新编码一遍,工作量从 1 加到 T。
2. 求和公式:写成闭式就是 T(T+1)/2,随 T 平方增长,长句很快就扛不住。
3. KV 缓存的直线:只编码新到达的词,总工作量与 T 成正比,是流式落地的关键。
流式环节还有两个绕不开的要点。其一是首词延迟:第一个目标词必须等前 k 个源词凑齐才能产出,这决定了整条链路的“冷启动”时间,ASR、网络传输都算在里面,需要提前预留。其二是不可回溯:同传一旦把某个目标词发给观众,就再也收不回来——所以模型宁可保守地把决策推迟到上下文更充分时,这正是 k 的意义。实践中,缓存的生命周期和内存上限也要精细管理,否则超长句会把显存撑爆,得不偿失。
小林把笔记纸一张接一张摊在桌上,新纸只补在末尾——这就是 KV 缓存;说出口的话如泼出去的水——这就是不可回溯。理解了这两点,流式同传系统就能把“词到 → 缓存 → 解码 → 送出”跑成一个滴水不漏的闭环。
延迟质量平衡:先定预算再调 k
出师前,老周问了小林最后一个问题:同传系统到底多快算快?小林张口就答:越快越好。老周摇头:与其追求“最快”,不如先问“观众能容忍多久”——这就是延迟预算。先定预算,再反推 k,才是负责任的调法。
把延迟预算写成公式:端到端延迟等于等 k 个词的时间加上解码传输的尾部开销。给定产品能容忍的延迟上限和模型的解码耗时,就能算出 k 的上界。在此基础上还要考虑语言对差异:中文到英文这类词序差异大的方向,词没读够就贸然输出,错误会像多米诺骨牌一样蔓延,k 通常要比英欧语对更大。
1. 每词时长 Δ:发言人平均每个源词占用的时间,是延迟的单位换算系数。
2. k 词等待:首个目标词最多要等 k 个源词的时长。
3. 尾部开销 δ:模型解码、网络传输、渲染刷新等带来的固定尾延迟。
4. 端到端延迟:两者相加就是观众真实感受到的延迟,预算约束下可反解出 k 的上界。
业务取舍通常有三种典型。追求极致实时的直播间,选小 k 保流畅、接受偶尔错译;正式国际会议同传,选大 k 保准确、接受一两秒延迟;对质量有硬指标的新闻直播,甚至可以退化到“半句缓冲”——这些本质上都是同一个模型在改 k 而已,这正是 wait-k 最迷人的地方。趋势上,自适应策略正在吞并固定 k 的领地,wait-k 的读写思想也被复制到流式大模型里——让模型一边接收用户补充输入一边调整输出,但底层逻辑始终没变:读多少、写多少,永远是一个需要回答的权衡。
小林终于出师。他把“落后 k 个词”五个字贴在工位最显眼的地方:快,从来不是贴着说话人跑,而是知道自己该落后几步。同传如此,实时 AI 系统更是如此。
AI 应用场景
视频会议实时字幕:把发言人的话“追着译”
阶段:推理部署与实时交互
解决的问题:传统会议同传要等发言人说完一整句才产出字幕,观众看到字幕时常已延迟 5 到 10 秒;wait-k 把首个译文延迟压到 k 个词的时长,观众几乎同步看到字幕。相当于小林学会了“先听 k 个词再开口”,而不是整句听完才动手。
具体案例:某大型云会议平台在多语字幕功能中部署 wait-k=4 的同传模型。发言人的音频经 ASR 输出词级结果后送入翻译模型,编码器按前缀增量读入,解码器同步产出英文/中文译文,字幕随发言人语速逐词刷新,实测端到端延迟约 1.2 秒,观众体验接近“同声字幕”。
直播与短视频侧译:给外语直播间装一个“同传耳机”
阶段:模型服务化与参数调优
解决的问题:直播间弹幕和外语解说需要实时翻译,语速快且句子碎片化,字幕既要跟得上又要错得不太离谱。wait-k 提供了一个可旋转的旋钮:对快语速主播调大 k 保质量,对高频互动调小 k 保实时,且同一个模型无需重训即可切换档位。
具体案例:某视频平台为外语游戏直播间部署 wait-k 侧译通道,k=3 时平均滞后约 0.6 秒(按每秒 5 词折算),观众在维持阅读节奏的同时能看到八成以上正确率的译文,主播突发言语梗时字幕误差也控制在可接受范围。
流式大模型“边说边想”:把 wait-k 借给智能助手
阶段:模型训练与在线推理
解决的问题:大模型流式输出时,用户可能中途追加或修正输入(“订明天……不对,订后天的票”),传统方案要等整句说完才能重新生成。借鉴 wait-k 的前缀读写思想:模型保持阅读用户消息前缀,边读边调整后续输出,支持被打断、被补充的自然对话节奏。
具体案例:某语音助手的连续对话模式采用“边读边写”调度:用户说到修正词时,模型已读前缀被更新,后续解码立刻切换条件,无需等整句话结束,响应速度提升约 40%,交互连续性明显改善。
Python 演示
"""wait-k 同声传译读写策略的最小演示: 模拟读写, 计算平均滞后, 构造训练样本."""import random class WaitKSimulator: """用 wait-k 规则模拟同传的读写过程.""" def __init__(self, src_len, k=3): self.src_len = src_len self.k = k def read_position(self, t): """生成第 t 个目标词时, 模型已读到的源词数(从 1 起, 封顶总长).""" return min(t + self.k - 1, self.src_len) def simulate(self): """返回 [(目标词序号, 已读源词数, 对齐源词, 滞后)] 列表.""" rows = [] for t in range(1, self.src_len + 1): g = self.read_position(t) aligned = min(t, self.src_len) rows.append((t, g, aligned, g - aligned)) return rows def average_lagging(self, rows): """平均滞后 AL, 单位是源词个数.""" return sum(row[3] for row in rows) / len(rows) def build_waitk_sample(src_ids, tgt_ids, k=None): """构造 wait-k 训练样本: 随机或指定 k, 输出 (源前缀, 目标前缀, 下一个目标词).""" if k is None: k = random.randint(1, max(1, len(src_ids) // 2)) pairs = [] for t in range(1, len(tgt_ids) + 1): read_n = min(t + k - 1, len(src_ids)) pairs.append((src_ids[:read_n], tgt_ids[:t - 1], tgt_ids[t - 1])) return pairs def main(): src_ids = [10, 11, 12, 13, 14, 15, 16] tgt_ids = [20, 21, 22, 23, 24, 25, 26] print("=== 不同 k 值的平均滞后(源词数) ===") for k in (1, 2, 4, 7): sim = WaitKSimulator(len(src_ids), k=k) al = sim.average_lagging(sim.simulate()) print(f"k={k}: AL={al:.2f}") print("\n=== k=3 的读写过程模拟 ===") sim3 = WaitKSimulator(len(src_ids), k=3) print("目标词 | 已读源词 | 对齐源词 | 滞后") for t, g, aligned, lag in sim3.simulate(): print(f" {t:>3} | {g:>4} | {aligned:>4} | {lag:>3}") print("\n=== universal wait-k 训练样本示例(k=3) ===") for i, (src_p, tgt_p, next_tgt) in enumerate( build_waitk_sample(src_ids, tgt_ids, k=3)[:4], start=1): print(f"样本{i}: 源前缀={src_p} 目标前缀={tgt_p} -> 预测 {next_tgt}") if __name__ == "__main__": main()
return min(t + self.k - 1, self.src_len)这是 wait-k 的核心公式:生成第 t 个目标词时已读源词数 = min(t+k-1, N),封顶防越界。rows.append((t, g, aligned, g - aligned))每一步都记录“已读源词数”与“对齐位置”的差,即该目标词的滞后量。return sum(row[3] for row in rows) / len(rows)把所有目标词的滞后量求平均,得到平均滞后 AL,单位是源词个数。k = random.randint(1, max(1, len(src_ids) // 2))Universal wait-k 的灵魂:训练时随机采样一个 k,让模型见多识广。pairs.append((src_ids[:read_n], tgt_ids[:t - 1], tgt_ids[t - 1]))前缀截断三件套:只给源前缀和目标前缀,让模型预测下一个目标词,训练形态与线上推理完全一致。
常见误区
误区我一直以为 wait-k 里的 k 是“处理速度档位”,k 越大模型读得越多、翻得越快,所以线上服务直接把 k 拉到最大。
正解k 是“滞后窗口”而不是速度档位。目标词 t 必须等到读完第 t+k-1 个源词才产出,k 越大,每句话都要等更久才开口,延迟越高、质量越好。就像小林等 8 个词再开口,观众要干等 8 个词的时间,速度反而更慢。k 更像油门和刹车的区别:k 小是踩油门抢实时,k 大是踩刹车保准确。
为何常见:把“读得多”误当成了“效率高”,混淆了输入吞吐与端到端延迟——读得快不等于观众看得快。
误区我以为 k=2 和 k=5 是两种不同模型,部署时要准备多个副本,按业务切流量,维护成本巨大。
正解Universal wait-k 在训练时随机采样 k 并施加前缀截断,一个模型能通吃所有 k;推理时动态改 k 即可,无需重训。就像小林训练时故意让不同语速的发言人给他练,练出一个“什么语速都能跟”的万能能力。部署上只需一份模型权重,k 只是读取时的一个参数。
为何常见:早期 wait-k 论文的“先训大 k 再逐步压低”流程,让很多人误以为 k 是模型的固有属性。
误区我以为 wait-k 要求源语言第 j 个词恰好对应目标语言第 j 个词,语序颠倒就算错,所以觉得中文到英文根本没法用。
正解wait-k 约束的是“读必须按前缀读、写必须按前缀写”的节奏,并不要求词与词位置一一对应;目标词的内容和顺序由模型自己决定,只要“写了多少”不超过“读了多少”即可。就像小林可以按中文语序听完、再用英文语序组织出来,只是没听全时调整空间有限。
为何常见:把“前缀约束”(读写都从前往后)和“单调对齐”(一一对应)混为一谈,前者是策略,后者是假设。
误区我以为只要把模型部署在好的 GPU 上、网络够快,实时翻译就流畅了;反正推理快,k 随便设。
正解网络和推理延迟只占一部分,wait-k 策略本身定义了“固定滞后 k 个词”的下界。k=5 时哪怕推理瞬间完成,观众也要等大约 5 个源词的时长才能看到首个译文。策略层的读写延迟是下限,工程优化只能逼近它,永远无法绕过它。
为何常见:把延迟完全归因于基础设施,忽略了算法策略自身就刻着一个延迟下界——再快的引擎也追不上“必须等 k 个词”的协议。
面试题
Q1. wait-k 策略中,k=1 时模型的表现是?
- A.听完整个句子才开口翻译
- B.读到第一个源词就开始翻译← 正确答案
- C.完全无法开始翻译任务
- D.输出永远为空不会结束
答案:B。k=1 意味着读入第 1 个源词后就开始产生第 1 个目标词,之后每读一个新源词就多写一个目标词,是最激进的“边听边译”档位。A 是 k=N(整句翻译)的行为;C 和 D 都与 wait-k 机制无关。
Q2. 其他条件不变时,增大 k 值一般会带来什么变化?
- A.延迟升高,翻译质量提升← 正确答案
- B.延迟降低,翻译质量下降
- C.延迟和质量都不受影响
- D.延迟大幅下降且质量提升
答案:A。k 是滞后窗口,k 越大模型等得越久、上下文越充分,首词延迟和平均滞后都上升,BLEU 质量通常随之改善。B 是减小 k 的效果;C 和 D 违背读写规则的基本方向。
Q3. 平均滞后(AL)指标度量的是什么?
- A.目标词相对源词的平均错位← 正确答案
- B.模型参数量的大小程度
- C.训练轮数的平均次数
- D.词表的大小规模程度
答案:A。AL 对每个目标词计算“产出时已读源词数 g_t”与“实际对齐位置 c_t”之差并求平均,直观含义是目标词平均比对应源词晚来几步。B、C、D 分别描述参数量、训练轮次、词表大小,与延迟无关。
Q4. full-sentence 翻译等价于 wait-k 的哪种情形?
- A.k 取值为零的情况
- B.k 取值为一的情况
- C.k 等于源句总词数← 正确答案
- D.k 等于目标句词数
答案:C。整句翻译先读完整个源句再解码,等价于读入数封顶在 N,即 k=N。k=0 没有定义(至少要读一个词才开始),k=1 是逐词同传,k 等于目标句词数则没有对应规则。
Q5. Universal wait-k 训练时是如何覆盖不同 k 值的?
- A.为每个 k 单独训练专用模型
- B.训练中随机采样 k 并施加前缀← 正确答案
- C.只用最大的 k 训练全部模型
- D.完全忽略 k 直接端到端训练
答案:B。Universal wait-k 每个训练步从 1 到 K 随机采样一个 k,按该 k 截断源前缀与目标前缀,再计算交叉熵损失,最终一个模型通吃所有档位。A 是负担最重的做法;C 只覆盖大 k;D 等于普通全句训练,无法学到前缀约束。
Q6. wait-k 流式推理中 KV Cache 的主要作用是?
- A.避免重复编码已读的源前缀← 正确答案
- B.扩大词表以提升翻译质量
- C.压缩模型减小部署体积
- D.将目标语言直接转换为源语言
答案:A。流式场景每来一个新源词,增量编码只需计算新词,复用之前算好的 Key/Value 缓存即可,复杂度从 O(T²) 降到 O(T)。B、C、D 分别属于词表、压缩、翻译方向的问题,与缓存机制无关。
Q7. 同传场景中 wait-k 策略控制的核心变量是?
- A.读多少源词才开始写目标词← 正确答案
- B.训练时使用多大的学习率
- C.选用哪种优化器训练模型
- D.分词器选用何种统计算法
答案:A。wait-k 的"wait"就是等待:先读入 k 个源词,之后逐词边读边写,核心变量是读写之间的滞后量 k。学习率、优化器、分词器都是训练与预处理细节,不构成 wait-k 的定义。
Q8. 相比整句翻译,wait-k 的典型优势有哪些?
- A.首个目标词的延迟更低← 正确答案
- B.可以边接收源词边输出← 正确答案
- C.模型参数量更少更省显存
- D.更契合实时流式交互场景← 正确答案
答案:ABD。wait-k 只等 k 个词就产出首个目标词,天然支持边读边写的流式交互,因此实时性远好于整句翻译。C 错误:wait-k 是一种推理决策策略,不改变模型结构与参数量,省显存来自 KV 缓存而非策略本身。
Q9. 影响最优 k 值选择的常见因素有哪些?
- A.语言对的词序差异大小← 正确答案
- B.说话人的平均语速快慢← 正确答案
- C.用户对延迟的容忍程度← 正确答案
- D.模型推理使用的显卡品牌
答案:ABC。词序差异大的语言对需要更大 k 来避免过早错译;语速快则每词占时短,可适当放大 k;用户能容忍的延迟预算直接给出 k 的上界。显卡品牌只影响推理速度,不改变最优 k 的语义。
Q10. 关于 wait-k 模型训练,下列说法正确的有哪些?
- A.用完整句模型预训练后微调← 正确答案
- B.训练样本按前缀规则截断← 正确答案
- C.从大 k 逐渐过渡到小 k 训练← 正确答案
- D.要求源词目标词严格逐词对应
答案:ABC。常见做法是用全句模型做预训练初始化,再通过前缀截断的样本微调;wait-k polish 则从大 k 逐步收窄到小 k。D 错误:wait-k 只约束读写前缀范围,不要求词级严格一一对应,目标词顺序由模型自行决定。