Qwen3.8-27B 的视频输入怎么传:那段被整体注释掉的抽帧示例

2026-08-16

翻 Hugging Face 上 Qwen/Qwen3.8-27B 的 model card 时,Video Input 这一小节很容易被一眼扫过去——代码块挺长,看着像是”视频输入的完整用法都在这儿了”。但把它按行拆开会发现,这个代码块里真正会执行的部分很短,而所有关于”怎么控制抽帧”的内容,是以注释形态存在的。

下面这篇就只做一件事:把这段示例的文本形态,以及它牵出的几个参数在仓库里能核到什么、核不到什么,逐条摆出来。核对日 2026-08-16,对应模型仓快照 1d4bf0f

先定位:这段在 model card 的哪儿

README.md 全文 583 行。Quickstart 相关的小节标题行是这样排的:## QuickstartREADME.md:225,往下依次是 ### Serving Qwen3.8:229)、### API Usage:243)、#### Chat Completions API:270),再往下才是四个具体输入形态的示例:##### Text-Only Input:282)、##### Image Input:343)、##### Video Input:375)、##### Instruct (or Non-Thinking) Mode:423),最后是 ##### Disable Preserved Thinking:469)。

## Quickstart(225 行)到 ## Best Practices(496 行)之间一共 6 个代码块,1 个 shell 加 5 个 python。Video Input 的那个 python 块占 README.md:377-420

顺带记一句 Quickstart 段首的原文(README.md:227):For streamlined integration, we recommend using Qwen3.8 via APIs.### Serving Qwen3.8 那一小节里没有任何一条服务启动命令,只有一个提示块和三条指向外部框架文档站的链接——这里只作为背景记一句位置,不展开。

会执行的那个请求,比想象中短

README.md:377-403 是会执行的那一段,原样照抄如下。下面这些代码、命令与参数一律是 model card 原文的文本,我们没有部署过任何推理框架、也没有发出过其中任何一个请求;模型仓内容随上游更新变动,看到的行号与措辞以官方最新说明为准。

from openai import OpenAI
# Configured by environment variables
client = OpenAI()

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "video_url",
                "video_url": {
                    "url": "https://qianwen-res.oss-accelerate.aliyuncs.com/Qwen3.5/demo/video/N1cdUjctpG8.mp4"
                }
            },
            {
                "type": "text",
                "text": "How many porcelain jars were discovered in the niches located in the primary chamber of the tomb?"
            }
        ]
    }
]

chat_response = client.chat.completions.create(
    model="Qwen/Qwen3.8-27B",
    messages=messages,
)

值得注意的是这个请求没有传的东西:没有 extra_body,没有任何采样参数,没有 reasoning_effort。它就是一条 OpenAI 兼容格式的 Chat Completions 调用,content 是一个数组,里面一项 "type": "video_url"video_url.url,一项 "type": "text" 带问题文本。图像那节(README.md:345-373)的结构与此对称,只是键名换成 image_url

前置环境按 README.md:274-280pip install -U openai,然后配 OPENAI_BASE_URLOPENAI_API_KEY 两个环境变量,README 原文这里用的是 your-base-url / your-api-key 两个占位符。

另外一个小细节:示例视频 URL 的路径段里写的是 /Qwen3.5/demo/,而模型是 Qwen3.8-27B。同样的路径段也出现在 README.md:357:440 两处图像示例里。只记录这个差异,不做延伸。

那十三行注释,是这段示例真正的信息量所在

README.md:405-417 这一整段每一行都以 # 开头,处于注释状态,原样照抄:

# When vLLM is launched with `--media-io-kwargs '{"video": {"num_frames": -1}}'`,
# video frame sampling can be configured via `extra_body` (e.g., by setting `fps`).
# This feature is currently supported only in vLLM.
#
# By default, `fps=2` and `do_sample_frames=True`.
# With `do_sample_frames=True`, you can customize the `fps` value to set your desired video sampling rate.
# chat_response = client.chat.completions.create(
#     model="Qwen/Qwen3.8-27B",
#     messages=messages,
#     extra_body={
#         "mm_processor_kwargs": {"fps": 2, "do_sample_frames": True},
#     }, 
# )

其中 README.md:411-417 这七行是被注释掉的那次 client.chat.completions.create(...) 调用本体,README.md:416 那行 # }, 行尾在原文里还带一个空格。也就是说:model card 里唯一一次出现 mm_processor_kwargs 的地方,是一段注释掉的代码;如果直接复制这个代码块,被执行的仍然是上面那个不带 extra_body 的请求。

这不是说这段注释没用——恰恰相反,README 关于视频抽帧的全部说明都压缩在这五行文字注释里。逐条看它说了什么、没说什么。

五个参数,README 各自说到哪一步

参数出处README 说明的内容README 未说明的内容
--media-io-kwargs '{"video": {"num_frames": -1}}'README.md:405(注释行内)它是”用 extra_body 配置抽帧”这条路径的前提,即 vLLM 需以此参数启动num_frames 的含义、-1 代表什么、其它取值、是否有默认值
num_framesREADME.md:405仅作为 --media-io-kwargs 的 JSON 内层键出现语义未单独说明;全 README 中只出现这 1 次
fpsREADME.md:406409410415可通过 extra_body 设置;By default, fps=2do_sample_frames=True 时可自定义取值范围、上限,以及与 num_frames 的关系
do_sample_framesREADME.md:409410415默认为 True;为 True 时可自定义 fps设为 False 时的行为
mm_processor_kwargsREADME.md:415(注释行内)作为 extra_body 的键,值为 {"fps": 2, "do_sample_frames": True}还接受哪些字段、由哪个组件消费;全 README 只出现这 1 次

再加一条限定,出自 README.md:407 原文:This feature is currently supported only in vLLM. ——即”用 extra_body 配置视频抽帧”这一能力,model card 明写当前只有 vLLM 支持。

三处对不上的地方,只陈述位置

第一处:fps=2do_sample_frames=True 这两个默认值,在随仓配置文件里找不到对应字段。

README.md:409 写的是 By default, fps=2anddo_sample_frames=True“。而 video_preprocessor_config.json 全文 21 行,逐个用 Python in 检查 fpsnum_framesdo_sample_framesmax_pixelsmin_pixels 五个关键词,结果全为 False;preprocessor_config.jsonconfig.json 同样不含(config.jsonfps 的检查结果也是 False)。README 未说明这两个默认值由哪一层提供。这一层我们没能在本仓库里核实——这是权重仓,没有源码工程可查。

第二处:带 --media-io-kwargs 的完整启动命令,README 全文里不存在。

README.md:405 以注释形式提到”当 vLLM 以 --media-io-kwargs ... 启动时”,但全文出现 vllm serve 的位置只有一处,在 ## Best Practices 第 3 条 “Processing Ultra-Long Texts” 下的 README.md:542,那条命令是讲 YaRN 长上下文的,里面并不含 --media-io-kwargs,而且命令中间还带着 README 原文自己写的 ... 省略占位。别处也没有给出完整命令。

第三处:chat 模板对 image_urlvideo_url 的判定条件不对称。

chat_template.jinja:8 的图像分支写的是 {%- if 'image' in item or 'image_url' in item or item.type == 'image' %},三个条件,其中包含 image_urlchat_template.jinja:19 的视频分支写的是 {%- elif 'video' in item or item.type == 'video' %},两个条件,不含 video_url。而 Video Input 示例传的正是 "type": "video_url""video_url": {...}README.md:387-390)。

这两处文本的差异就是事实本身。请求在到达模板之前是否会被推理框架改写,我们无法从这个仓库里核实,所以也不推断运行时会发生什么。

顺便记下模板命中后的渲染结果:图像渲染为 '<|vision_start|><|image_pad|><|vision_end|>'chat_template.jinja:18),视频渲染为 '<|vision_start|><|video_pad|><|vision_end|>':29);add_vision_id 为真时会在占位符前加 'Picture N: ' / 'Video N: ';system 消息里带图或带视频会直接抛异常,chat_template.jinja:10raise_exception('System message cannot contain images.'):21 是对应的视频版本。这几个特殊 token 在 tokenizer_config.jsonadded_tokens_decoder 里对得上:248053 <|vision_start|>248054 <|vision_end|>248055 <|vision_pad|>248056 <|image_pad|>248057 <|video_pad|>config.json:5image_token_id248056config.json:121video_token_id248057

那视频预处理配置里到底有什么

既然抽帧那三个键都不在,不妨把 video_preprocessor_config.json 全部 9 个键列完(文件共 21 行):

字段行号
size.longest_edge25165824:3
size.shortest_edge4096:4
patch_size16:6
temporal_patch_size2:7
merge_size2:8
image_mean[0.5, 0.5, 0.5]:9-13
image_std[0.5, 0.5, 0.5]:14-18
processor_class"Qwen3VLProcessor":19
video_processor_type"Qwen3VLVideoProcessor":20

它和图像那份 preprocessor_config.json 只有三处不同:size.longest_edge1677721625165824)、size.shortest_edge655364096)、以及末尾的类型键(image_processor_typevideo_processor_type)。归一化参数、patch_size=16temporal_patch_size=2merge_size=2processor_class 这几项两个文件完全一致。

还有一处口径差异要记:README.md:561 原文说 the size parameter in the released video_preprocessor_config.json is conservatively configured,并建议把 longest_edge 改为 469762048(原文括注对应 224k video tokens),示例 JSON 是 {"longest_edge": 469762048, "shortest_edge": 4096};而仓库实际发布值是 25165824video_preprocessor_config.json:3)。shortest_edge 两处一致,都是 4096。README 同时写明也可以通过引擎启动参数覆盖默认值,并给了两个外部 PR 链接(README.md:566,vLLM PR 34330 / SGLang PR 18467)——那两个链接的内容不在本仓库内,我们没有访问,所以这条做法的实现细节这里核不到。

至于 longest_edge 这个数值的单位与换算,README 只在视频那处括注了一个对应关系,没有给通用公式;preprocessor_config.json16777216 / 65536 对应多少 token,仓库里没有说明,这里不做任何推算。

想动这块时,能查到哪一步

把上面的东西倒过来用,判定动作大致是这样的:

  • 想确认自己传的视频结构对不对——去比对 README.md:377-403 这个会执行的请求,看键名是 video_url 还是别的。
  • 想确认抽帧参数能不能传——先看你的推理框架是不是 vLLM,因为 README.md:407 明写这个能力当前只在 vLLM 支持;再看服务是不是带 --media-io-kwargs 起的,README 只说了这是前提,没给完整命令。
  • 想确认 fps=2 这个默认值从哪来——在 preprocessor_config.jsonvideo_preprocessor_config.jsonconfig.json 三个文件里搜 fps,三处都搜不到,这条线在模型仓内到此为止,只能回到框架侧的文档。
  • 想确认视频尺寸相关的默认值——直接看 video_preprocessor_config.json:3-4,并记住 README 建议值与发布值不是一个数。

### Serving Qwen3.8 那节把”具体怎么起服务”指向了 SGLang、vLLM、TokenSpeed 三个外部文档站(README.md:238-240)。这三个站的内容不在本文覆盖范围内,抽帧那条路径的完整参数语义,多半得回到框架自己的文档去找。

最后补一句 model card 自己的限定:README.md:16 写托管版本会带更多生产特性,原文结尾是 The service is coming soon. Stay tuned for updates.——采集时那些托管特性是”即将推出”状态,不能当成现有能力。config.json:120transformers_version 的值是 5.8.0.dev0,也是个开发版版本号。这类标记照实记下来,比事后被口径差异绊一跤要省事。

延伸阅读


本文依据 Hugging Face 仓库 Qwen/Qwen3.8-27B 的 model card 与随仓配置文件 (config.jsongeneration_config.jsonpreprocessor_config.jsonchat_template.jinja 等)整理, 核对日 2026-08-16,对应仓库快照 1d4bf0f。 本文内容为 model card 与配置文件口径,我们没有下载权重、没有部署、也没有推理过这个模型, 因此不涉及生成质量、推理速度与显存占用的任何描述;文中所有评测数字均为 model card 自述,我们没有复现。 模型仓库内容随上游更新而变动,请以官方最新说明为准。 安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。