Choose the Next Token
从 logits 走到采样结果
追踪模型输出如何进入采样器,再成为可提交的请求状态。
采样结果与请求状态更新属于不同阶段,必须通过元数据保持对应。
01模型输出还不是请求输出
模型前向返回用于选择的分数与相关状态。采样器结合各请求参数、约束和 draft 信息形成选择或接受结果;请求层随后才知道哪些输出可以提交。读 ModelRunner.execute_sample 时先追踪 sampler_inputs 如何由序列元数据建立,再进入模型的 sample 路径。
s04_sampling.py
# Framework pseudocode for the sampling boundary.
sampler_inputs = prepare_sampler_inputs(
sequence_metadata, input_metadata,
)
sampler_output = model.sample(
model_output=main_output,
sampler_inputs=sampler_inputs,
)
step_state = StepState(sequence_metadata, sampler_output)
# Sampling can choose tokens or verify draft candidates.
# Post-processing commits accepted positions and stop states.
ready_outputs = post_process_when_ready(step_state)
# Under ZOS, readiness can cross a round boundary.02策略参数不能丢失请求身份
贪心、温度、top-p 与约束输出影响不同的选择环节。组批后,各请求仍要保留自己的参数和随机状态,draft 验证还要关联候选位置与接受长度。教学片段只描述框架接口,不把一个简单 argmax 或随机抽取函数当作上游完整采样器。
03提交状态要等待所需依赖
后处理把采样结果写回序列,更新接受位置、结束标记和对外输出。开启 ZOS 时,这部分工作可能在下一轮前向发出后进行。阅读时区分采样已产生、状态已落账和结果已发布三个时刻,才能解释为什么一轮返回的输出未必来自当前采样。
04结构化输出还维护一份语法状态
官方生产设计:官方部署文章将结构化输出放进生成链路:已确认的前缀决定当前语法状态,状态再决定下一步的合法 token 集合。采样必须遵守这份集合。它约束输出的语法与结构,字段内容是否符合事实仍由具体任务决定。 开源核对:固定版本的 sampler.py先把已接受的 token 推进请求自己的 matcher,再为各个 draft 位置临时推进状态、生成 mask,最后回滚临时推进。mask 在采样与 draft 验证之前应用,因此语法状态也必须遵守“只有确认的前缀才能长期保留”的规则。
TRY IT YOURSELF
动手想一想
选一个带结束条件的请求,画出 model_output、sampler_output、序列状态与 RequestOutput 四种对象之间的依赖。
把这个机制,加入你的工具箱。