vLLM 支持无失真文本水印了Gumbel-max 是怎么混进采样管线的原文vLLM Blog - Watermarking in vLLMhttps://vllm.ai/blog/2026-09-24-watermarking-in-vllm给 LLM 输出加水印这件事学术界喊了很久真正落到主流推理引擎里的方案一直不多。2026 年 9 月 24 日vLLM 官方博客宣布支持基于 Gumbel-max 算法的无失真文本水印直接集成进 Model Runner v2 的采样管线由 Mistral 与 Red Hat 的工程师合作实现并通过多个 PR 融合了 GPU kernel、双键方案和上下文去重兼容投机解码。这篇带你把它的原理和工程实现拆开看清楚。一、为什么文本水印难做图片、音频可以靠人眼听不出来的微小扰动夹带水印但文本是离散的改一个词就是另一个词。vLLM 的思路是反过来不去扰动文本本身而是影响生成过程让这种影响事后可检测却不改变模型输出的期望分布。官方给可行方案列了四个要求非失真Non-distortion、鲁棒性Robustness、速度Speed、检测依赖最小化Minimal detection dependencies。Gumbel-max 方案在前三条上都有干净的答案。二、核心原理Gumbel-max trick模型给每个候选 token 一个概率。采样时为每个候选独立抽一个均匀随机数变换成 Gumbel 噪声加到 log 概率上取 argmax一个很漂亮的结论是这样选出来的 token分布与按原始概率直接采样完全一致。事实上 vLLM 的标准采样路径本来就在用这套过程——水印要做的只是把真随机换成可复现的伪随机。用一段示意代码表达下面是我自己写的演示版本非官方实现仅帮助理解importnumpyasnpdefgumbel_max_sample(logits,key,ctx,prf):# logits: 候选 token 的原始 logit不需要先过 softmaxnlen(logits)# 用伪随机函数 PRF 为每个候选 token 生成均匀随机数unp.array([prf(key,ctx,i)foriinrange(n)])# 均匀随机数变换为 Gumbel 分布噪声g-np.log(-np.log(u))# 加噪后取 argmax等价于按模型概率采样returnint(np.argmax(logitsg))参数说明logits 不经过 softmax 直接加噪避免额外的归一化开销且更易并行key 是水印密钥ctx 是最近的 token 上下文默认取最后 4 个 token保证几乎每一步的噪声都不同prf 返回值在 (0,1) 之间均匀分布。函数返回选中 token 的下标。关键的改造在这一行独立的均匀随机数被替换为 PRF伪随机函数的输出输入是密钥、token id 和最近上下文。三个成分各司其职——token id 让每个候选噪声不同上下文让每步噪声不同密钥让没有 key 的人无法预测这个模式。于是非失真有了精确的保证对密钥取期望选中某个 token 的概率恰好等于模型给它的概率。水印既不偏爱某些词也不改变写作风格。而检测之所以可行是因为同样的 key 和上下文能完整重放生成时的噪声序列。检测器拿回文本重新计算每个位置的伪随机值做统计检验即可不需要访问模型本身。三、工程落地采样管线里的三件事原理一句话落地是另一回事。vLLM 的实现初始 PR #54053有三个值得注意的点。第一接口分层。初始实现把 GPUWatermarkSampler 接到一个算法特定的 Watermarker 抽象上不同水印方案可以共享同一套请求与批处理逻辑。第二融合 GPU kernel。朴素实现要为一个 batch 物化形如 [batch, vocab] 的噪声张量临时存储和显存流量都不小。vLLM 把伪随机数生成、Gumbel 变换和 argmax 归约融合成单个 GPU kernel其中 Philox 生成器每次调用产出四个随机值kernel 一次处理四个连续 token id。第三per-row mask。同一个融合采样器同时服务两类请求水印请求走带密钥的噪声普通请求或重复上下文走普通随机性靠每行一个掩码区分。四、与投机解码共存双键方案投机解码会让事情变复杂draft 分布 propose tokentarget 分布决定接受与否。如果对两个分布施加同一个水印各自分布虽然不变但重叠度下降接受率会被拉低。vLLM 的解法是双键实现PR #56122一个 key 用于被接受的草稿 token另一个 key 用于 target 残差和 bonus token。两个分布各自独立采样接受率保持正常。代价在检测端最终文本里两种 key 水印的 token 混在一起检测时必须用两个 key 分别打分再合并信号会被稀释。合并权重可以校准——草稿 token 往往在容易的位置被接受熵更低携带的水印信号也更弱权重就应相应调低。五、质量与吞吐表现官方博客给出的数据以官方文档为准Qwen3.5-27B 开启双键水印后GSM8K 为 93.0%无水印 94.2%、MBPP 为 79.2%无水印 77.2%、IFEval 为 90.7%无水印 91.9%误差条相互重叠质量没有系统性下降。吞吐方面Qwen3.5-27B 配 MTP-3、batch size 从 1 到 256水印与无水印曲线基本重叠八个 key 的平均匹配吞吐变化在 -1.1% 到 2.0% 之间没有明显减速。需要提醒的是单 token 层面的非失真不等于完整序列层面的多样性不受影响官方博客在 “Maintaining output diversity” 一节专门讨论了这个限制及对策细节以官方文档为准。六、怎么用启动服务时通过 watermark-config 开启vllm serve mistralai/Mistral-7B-Instruct-v0.3 \ --watermark-config {algorithm:gumbel,key:42}参数解释algorithm 指定水印算法为 gumbelkey 是整数形式的水印密钥检测端必须持有相同的 key 和匹配的 tokenizer。vLLM 同时提供了一个最小 HTTP 检测服务示例用于对文本做水印校验配置与检测示例见官方水印文档版本细节未验证最新版本。七、给开发者的三点启发无失真不是输出几乎不变而是分布层面的严格等价这是 Gumbel-max 方案最值得学的地方。可检测性来自随机源可复现。PRF 把随机变成带密钥的确定性是整个方案从学术走向工程的那座桥。水印放在推理引擎的采样层而不是生成后的文本后处理才可能做到无损、低开销且兼容投机解码。如果你在做推理服务或 LLM 应用平台这个集成位置的选择值得参考。
