Qwen3.8-27B 的 MTP:自述多步训练,配置里只有一层
把 Qwen3.8-27B 的 model card 打开,滚到 “Model Overview” 那一节(README.md:32–README.md:53),你会发现它是一张相当规整的参数表:隐藏维度、词表大小、层数、注意力头数、FFN 中间维度,每一项后面都跟着一个具体的数。我们把这些数逐行拿去和随仓的 config.json 对,绝大多数都能一一对上——Hidden Dimension: 5120 对 text_config.hidden_size = 5120(config.json:18),Number of Layers: 64 对 num_hidden_layers = 64(config.json:98),Intermediate Dimension: 17,408 对 intermediate_size = 17408(config.json:20)。
对到倒数第二行时卡住了。这一行是:
- MTP (Multi-Token Prediction): trained with multiple steps
出处是 README.md:52。这一节开头的 Type: Causal Language Model with Vision Encoder(README.md:34)与 Training Stage: Pre-training & Post-training(README.md:35)本来就是文字说明,不带数字;而从 Number of Parameters: 27B(README.md:37)开始的各个参数行,冒号后面都跟着一个具体的数——唯独 MTP 这一行没有。
而 config.json 那边偏偏有数字,还是个很小的数字。
两处原文,各自摆在哪
config.json 的 text_config 下共 34 个键(我们用 Python 数的,口径见文末命令),其中有两个以 mtp_ 开头:
| 字段名 | 值 | 行号 |
|---|---|---|
mtp_num_hidden_layers | 1 | config.json:95 |
mtp_use_dedicated_embeddings | false | config.json:96 |
也就是说,这件事在两个层面上各有一句话:
- model card 层面(
README.md:52):trained with multiple steps,一个自然语言短语,没有数字。 - 发布配置层面(
config.json:95):mtp_num_hidden_layers的值是1。
我们采集这份快照的时间是 2026-08-16,对应 Hugging Face 仓库 Qwen/Qwen3.8-27B 的 1d4bf0f。上面两个数字都是从这份快照里逐字读出来的。
为什么不能把「multiple」和「1」放在一起做减法
看到「多步」和「1 层」并排,第一反应容易是「文档说多、配置说一,矛盾了」。但这两个词说的根本不是同一个量纲:
README.md:52那句里的steps,字面上修饰的是trained,讲的是训练环节的事;config.json:95里的mtp_num_hidden_layers,字面上是层数(hidden layers)。
训练时用了几步,与发布配置里写着几层,是不是同一件事,我们无法从这个仓库的任何一个文件里确认。 这个仓库是模型权重仓,不是代码仓:config.json:3 里写的 architectures 是 ["Qwen3_5ForConditionalGeneration"],但这个类的实现不在本仓,本仓能读的只有 model card、几个 JSON 配置、tokenizer 相关文件和 chat_template.jinja。没有建模代码,就没有办法知道 mtp_num_hidden_layers 这个键在加载与推理时到底被谁读走、怎么用。
所以我们能做的,只有把两处原文并排陈述,标明各自的行号,然后停在这里。不推断哪一处「才是对的」,不推断为什么一处有数字另一处没有,也不拿这个差异去评价这个模型或这个团队——这不是本文的目的,我们也没有依据。
顺带把第二个字段也记上:mtp_use_dedicated_embeddings 的值是 false(config.json:96)。model card 里与 MTP 有关的表述就只有 README.md:52 那半句,没有再展开这个字段。它为 false 意味着什么,同样属于「本仓文件没有说明」的范畴。
在这个仓库里处境相同的字段不止 MTP 这两个。text_config 里还有 attn_output_gate: true(config.json:11)、output_gate_type: "swish"(config.json:100),顶层还有 language_model_only: false(config.json:6)——后面这个键名在 README.md 全文都查不到。这些字段我们同样只能照录取值:它们在加载与推理时具体怎么被使用,本仓没有可读的实现,我们一律未能确认。
这里也顺便说清本文不做什么:我们不解释 MTP 是什么、用来干什么、放在推理链路的哪一环。这个仓库里对它的全部描述就是 README.md:52 那半句话,加上 config.json 里的两个键。除此之外的任何说法,都得从别处搬,而本文的事实边界就到这份快照为止。
这 1 层不在那 64 层里
还有一个容易顺手做错的动作:把 mtp_num_hidden_layers 的 1 和 num_hidden_layers 的 64 加起来,或者认为它是从 64 里划出来的一层。
text_config.layer_types 是一个字符串数组,位于 config.json:21-86,我们用 Python 读出来数过:长度正好 64,与 num_hidden_layers = 64(config.json:98)相同;数组里的取值只有两种,"linear_attention" 与 "full_attention",其中 full_attention 16 项、linear_attention 48 项。也就是说,这个 64 项的数组里没有任何一项是留给 MTP 的——它是一个独立字段,和 layer_types 各说各的。
这 64 项的排布本身是有规律的:full_attention 的 0 基下标是 3, 7, 11, …, 63,换成第几层就是第 4, 8, 12, …, 64 层,相邻两个之间的间距恒为 4;text_config 里另有一个 full_attention_interval,值正好是 4(config.json:15),而 64 ÷ 4 = 16,与 full_attention 出现的次数相同。我们只陈述这个数值上的一致,不解释这个字段在推理时如何被使用——本仓没有推理代码可查。而 mtp_num_hidden_layers 完全不在这套排布里,它既不出现在 layer_types 的取值中,也不参与上面这组算术。
64 与 1 之间该不该做加减,config.json 与 model card 都没有给出说法,我们不替它做。这一条和上一节是同一个道理:配置里两个数字挨在一起,不等于它们可以放进同一个算式。
这不是孤例:那张表里的三类行
把 “Model Overview” 整张表逐行拿去核对,结果其实可以分成三类,MTP 属于第三类:
第一类:README 有数、config 有同名字段、数值一致。 这类占多数,除了开头那三行,还有 Token Embedding: 248,320 (Padded) 对 vocab_size = 248320(config.json:117)、Number of Attention Heads: 24 for Q and 4 for KV 对 num_attention_heads = 24 与 num_key_value_heads = 4(config.json:97、config.json:99)、Number of Linear Attention Heads: 48 for V and 16 for QK 对 linear_num_value_heads = 48 与 linear_num_key_heads = 16(config.json:90、config.json:89)。这类行你想复核,打开 config.json 搜字段名就行。
第二类:README 有数,但 config 里根本没有承载它的字段。 典型是 Number of Parameters: 27B(README.md:37)——config.json 里没有任何一个字段写参数量,我们也没有下载权重,所以这个 27B 只能作为「model card 自述」引用,无从核对。同类的还有 Rotary Position Embedding Dimension: 64(README.md:48):config.json 里没有叫这个名字的键,只有 head_dim = 256(config.json:16)和 partial_rotary_factor = 0.25(config.json:102);我们用 Python 算了一次,256 × 0.25 = 64.0,数值与 README 相同,但这是我们做的算术核对,config.json 本身并没有写出 64 这个数。再往下一行的 Context Length: 262,144 natively and extensible up to 1,000,000 tokens.(README.md:53)也是半个一致:max_position_embeddings = 262144(config.json:93)对得上,而 1,000,000 在发布的配置里没有任何字段承载。
第三类:README 没给数,config 给了数。 全表就 MTP 这一行。
把这三类摆在一起,MTP 那行的性质就清楚了:它不是「README 和 config 打架」,而是这张表里唯一一处方向反过来的地方——通常是文档给结论、配置给细节,这一行反倒是配置更具体。
你自己怎么复核这两处
不需要下载权重,也不需要加载模型。model card 与几个 JSON 配置文件在 Hugging Face 仓库页面上就能直接看,config.json 一共 4,312 字节、140 行,肉眼翻也翻得完。
我们数键的命令原样如下(在放着 config.json 的目录里执行):
python -c "
import json
d=json.load(open('config.json',encoding='utf-8'))
print('n top', len(d.keys()), 'n text', len(d['text_config'].keys()), 'n vision', len(d['vision_config'].keys()))
"
输出是 n top 11 n text 34 n vision 14。两个 mtp_ 字段就在这 34 个 text_config 键里。
一点命令行层面的提醒,与模型仓本身无关:上面这种把多行 Python 塞进 -c 的写法,在 Linux/macOS 的 shell 里可以直接粘;在 Windows 的 PowerShell 里,双引号与换行的处理规则不同,更省事的做法是把这几行存成一个 .py 文件再执行。这属于命令行的通用写法,不是这个模型仓的内容。
至于 README 那一侧,README.md 全文 583 行,MTP 那句就在第 52 行,检索关键词能一次定位。我们另外做过一次关键词检索:
grep -n "Qwen3_5\|qwen3_5\|ForConditionalGeneration\|AutoModel\|AutoProcessor\|dtype\|DeltaNet\|Gated" README.md
AutoModel / AutoProcessor 在 model card 里零命中——也就是说,你在 model card 里找不到一段本地 Transformers 加载代码,自然也就找不到「mtp_num_hidden_layers 在加载时怎么用」的线索。同一次检索里还有一个可以顺手记下的事实:README.md 全文没有写出所需的 transformers 版本号,而 config.json:120 的 transformers_version 写的是 "5.8.0.dev0",带一个 .dev0 后缀。这个版本是否已发布、能不能加载本配置,我们没有安装过,也无从核实。以上这些检索结果,就是我们把 MTP 这条线索追到此为止的直接原因。
收在哪里
写这一篇的意义不在于给 MTP 下定义,而在于示范一种核对姿势:model card 的一行话和配置文件的一个键,即使讲的是同一个缩写,也未必是同一个量纲,不要替它们互相换算。 在只有权重和配置、没有建模源码的仓库里,能核到「两处原文分别是什么、各在第几行」这一步,就已经是这份材料能支持的全部结论了。再往前一步就是猜。
如果你要在自己的技术方案里引用「Qwen3.8-27B 的 MTP」,稳妥的写法是把两句原文都抄上、各自标明出处,而不是只抄其中一句然后补一个自己算出来的数。
延伸阅读
- 从头读起:Qwen3.8-27B 是什么:一个模型仓里有哪些文件、各自负责什么
- 本专题共 35 篇,完整分组目录见专题页
- Qwen3.8-27B 的 RoPE 维度 64:config.json 里找不到对应字段
- Qwen3.8-27B 的词表 248,320 与特殊 token:padded 是什么意思
本文依据 Hugging Face 仓库 Qwen/Qwen3.8-27B 的 model card 与随仓配置文件
(config.json、generation_config.json、preprocessor_config.json、chat_template.jinja 等)整理,
核对日 2026-08-16,对应仓库快照 1d4bf0f。
本文内容为 model card 与配置文件口径,我们没有下载权重、没有部署、也没有推理过这个模型,
因此不涉及生成质量、推理速度与显存占用的任何描述;文中所有评测数字均为 model card 自述,我们没有复现。
模型仓库内容随上游更新而变动,请以官方最新说明为准。