Wan-Streamer v0.2 同一段视频两次结果不同——随机性从哪一项来?

文章导读
同一段视频、同一句指令,两次返回的表述差别很大,先别急着把原因归到“模型天生随机”。在 Wan-Streamer v0.2 这类视频理解链路里,能被你控制、又确实会改变输出的项通常集中在三处:输入本身(抽帧位置、帧数、分辨率、是否带音轨、视频是否被重新编码)、请求参数(采样温度、top_p、seed、最大输出长度、是否流式)、提示词顺序(任务指令在前还是问题在前)。排查顺序建议是:先确认差异是否稳
📋 目录
  1. Ⅰ 同一样本连续调用五次并保存原文
  2. Ⅱ 固定所有可配置参数后再跑一轮
  3. Ⅲ 调换指令与问题的先后位置
  4. Ⅳ 把请求与返回整理成可比对的日志
A A

同一段视频、同一句指令,两次返回的表述差别很大,先别急着把原因归到“模型天生随机”。在 Wan-Streamer v0.2 这类视频理解链路里,能被你控制、又确实会改变输出的项通常集中在三处:输入本身(抽帧位置、帧数、分辨率、是否带音轨、视频是否被重新编码)、请求参数(采样温度、top_p、seed、最大输出长度、是否流式)、提示词顺序(任务指令在前还是问题在前)。排查顺序建议是:先确认差异是否稳定复现,再把参数全部固定住跑一轮,最后单独调整提示词顺序;三项分开验证,才不会把传参不一致误判成模型随机。

如果固定参数后连续五次返回仍在同一处出现差异——比如镜头顺序、人物数量、时间点描述——随机性多半来自采样环节或抽帧方式,属于模型侧;如果差异随之消失,说明此前是传参或输入不一致。适用场景是同一视频同一提示词的可复现性排查。操作动作:五次调用原文留档、参数固定后复跑、提示词顺序对调各一轮。边界要清楚:这套方法只能定位差异来自哪一项,不能证明某一版输出“更正确”。

同一样本连续调用五次并保存原文

第一步不是改任何东西,而是把“两次不同”变成可看的证据:同一视频文件、同一提示词、同一套参数,连续调用五次,每次把请求和原文落盘。注意不要用聊天界面点两次来判断,界面可能自带上下文或默认参数差异,用脚本或固定请求体更可控。

下面是一个可替换的调用骨架,client 和字段名按你实际的 SDK 或 HTTP 接口改,重点是保存逻辑而不是接口细节:

# run_repeat.py
import json, hashlib, pathlib, time

OUT = pathlib.Path('runs/v02-repeat'); OUT.mkdir(parents=True, exist_ok=True)
VIDEO = 'samples/clip-01.mp4'
PROMPT = '描述这段视频里发生了什么,按时间顺序列出关键动作。'
PARAMS = {'temperature': 0, 'max_tokens': 512, 'seed': 1234}

def call_once(i):
    t0 = time.time()
    resp = client.generate(video=VIDEO, prompt=PROMPT, **PARAMS)  # 替换为实际调用
    text = resp.get('text') or resp['output'][0]
    return {
        'run': i,
        'elapsed': round(time.time() - t0, 2),
        'video_sha1': hashlib.sha1(open(VIDEO, 'rb').read()).hexdigest(),
        'prompt': PROMPT,
        'params': PARAMS,
        'text': text,
    }

for i in range(1, 6):
    rec = call_once(i)
    (OUT / f'run-{i:02d}.json').write_text(json.dumps(rec, ensure_ascii=False, indent=2), encoding='utf-8')
    (OUT / f'run-{i:02d}.txt').write_text(rec['text'], encoding='utf-8')

保存方式建议两套并存:json 存完整记录,txt 只存返回正文。txt 便于直接 diff(diff -u run-01.txt run-02.txt),json 便于事后核对参数是否真的没变。同时记下视频文件的 sha1,才能证明五次用的是“同一样本”,而不是某个被重新编码过的副本。

标注差异位置时按四类分开记,不要笼统写“两次不一样”:出现或遗漏的数字与时间点、人物与物体数量、镜头/动作的先后顺序、以及视频里根本没有的内容。如果五次里差异全部落在第四类,那更可能是模型产生了并非视频内容的信息;如果集中在第二、三类,抽帧覆盖范围往往是重点怀疑对象。

固定所有可配置参数后再跑一轮

五次结果有波动,常见原因不是模型,而是自己每次少传或多传了一项。先列清单,把能固定的一次性固定,再重跑一轮,观察差异是否收窄。

Wan-Streamer v0.2 同一段视频两次结果不同——随机性从哪一项来?
类别需要固定的项常见疏漏
采样temperature、top_p / top_k、seed、max_tokens界面上有默认温度,脚本里又传了另一个
视频输入抽帧帧数或帧率、固定时间点、分辨率与缩放、是否带音轨每次上传时被平台重新转码,帧率变了
调用方式流式开关、超时、重试次数、模型版本号超时重试后实际发了两次请求

两轮对比建议只记四列,够用且不容易自我说服:

轮次参数状态五次返回是否出现差异差异落在哪一类
A 轮沿用平时习惯,未逐一核对记录实际结果按上节四类标注
B 轮按清单全部显式传入记录实际结果按上节四类标注

参数是否真的生效,不能只看自己写了什么,要看服务端认了什么。可行的验证方式有三种:把实际发出的请求体完整落盘,比对是否与预期一致;如果返回里带参数回显或 usage 字段,核对回显值;用极端值试探,例如把 max_tokens 设得很小,若输出长度毫无变化,说明该参数没有按预期传到服务端。seed 这类字段尤其需要试探——部分服务实现会忽略未支持的字段,这时“固定 seed”并不能带来可复现性,只能靠 temperature 低值和重复调用来观察。

调换指令与问题的先后位置

输入和参数都固定后,剩下的变量就是提示词结构。这里只动顺序,不动措辞,否则无法判断是哪一项起作用。

// 顺序 A:任务指令在前,问题在后
{
  "input": "你是视频内容整理助手,只描述画面中可见的内容。",
  "prompt": "请按时间顺序列出这段视频里的关键动作。",
  "video": "samples/clip-01.mp4"
}

// 顺序 B:问题在前,任务指令在后
{
  "prompt": "请按时间顺序列出这段视频里的关键动作。",
  "input": "你是视频内容整理助手,只描述画面中可见的内容。",
  "video": "samples/clip-01.mp4"
}

两种顺序各跑五次,返回重点只需要盯三件事:输出是否变成逐条列举还是一段叙述、开头是先给答案还是先复述任务、有没有出现视频外的补充内容。这些差异比措辞差异更稳定,也更容易在日志里判断。

Wan-Streamer v0.2 同一段视频两次结果不同——随机性从哪一项来?

判断哪一版更稳,看的是同一顺序内部五次之间的一致性,而不是哪一版看起来更“好”。如果顺序 A 五次都是分条且条数接近,顺序 B 时而分条时而整段,那么在当前版本与当前参数下,把任务指令放在前面的结构更值得沿用。这个结论只对这套视频样本和这套参数成立,换视频或换参数需要重新跑。

把请求与返回整理成可比对的日志

前面三步如果只是临时看结果,问题还会反复出现。把每次调用写成一条结构化日志,后续任何一次波动都能回溯到具体输入。

字段建议覆盖:trace_id、时间、模型名与版本、视频指纹(sha1、时长、分辨率、帧率、转码命令)、抽帧配置、提示词原文与其 hash、提示词顺序版本标记、全部请求参数、原始请求体、原始返回体(含结束原因与用量字段)、耗时、重试次数。

{
  "trace_id": "v02-2024-clip01-run03",
  "ts": "记录调用时刻",
  "model": "wan-streamer",
  "model_version": "0.2",
  "video": {
    "path": "samples/clip-01.mp4",
    "sha1": "<文件指纹>",
    "duration_s": 0,
    "fps": 0,
    "resolution": "宽x高",
    "transcode_cmd": "无或实际命令"
  },
  "frame_config": {"frames": 16, "mode": "uniform"},
  "prompt": {
    "order": "A",
    "text": "描述这段视频里发生了什么,按时间顺序列出关键动作。",
    "hash": "<提示词hash>"
  },
  "params": {"temperature": 0, "top_p": 1, "seed": 1234, "max_tokens": 512, "stream": false},
  "request_body": "原始请求体",
  "response": {"text": "返回原文", "finish_reason": "记录值", "usage": "记录值"},
  "elapsed_ms": 0,
  "retries": 0
}

用两条日志定位差异时,按这个顺序比:先比 video.sha1 与时长分辨率,不同就先排除输入差异;再比 params 与 prompt.hash、prompt.order,任何一项不同就是可解释的差异来源;若前面全部一致而 response.text 仍有区别,才把怀疑对象放到采样环节,用更低 temperature 或固定 seed 再跑几次确认。最后把两条 response.text 做 diff,标注差异落在哪一类,写回日志备注字段。

这套留档不要太重:字段够用就行,视频本身不必入库存副本,指纹加转码命令已经能还原输入。真正需要长期保留的是参数、提示词顺序标记和返回原文,这三样决定了下次出问题时能不能立刻判断是新变量还是老随机。