☰
QWEN技术资料拆解:模型选型、SFT/RLHF与长上下文显存避坑
2026/10/26 10:37:09 网站建设 项目流程

简介:QWEN 技术报告 PDF 面向大语言模型研究者、算法工程师与高校学习者,系统梳理通义千问(Qwen)第一代开源模型的技术路线,适合模型选型、论文研读与实验复现参考。压缩包共 1 个 PDF 文件,约 1.53MB,为完整英文技术报告,涵盖预训练数据配比与分词、模型架构、位置编码与上下文长度扩展、训练流程及实验结果,并介绍监督微调、RLHF 等人类对齐方法,以及 Qwen-Chat、Code-Qwen、Math-Qwen-Chat 等分支。报告还讨论对话模型在工具调用、规划、代码解释器等代理任务中的表现,便于读者理解基座模型与聊天模型的能力差异,并据此把握开源模型的评测口径与适用边界。当前已有 1696 人学习,适合作为入门 Qwen 系列、撰写综述或搭建评测基线时查阅,尤其对想复现开源大模型训练与对齐流程的读者更有参考价值。

1. 拿到一份 20 多页的技术资料,多数人第一步就走错了

上周有位做企业知识库的同行发来一份 QWEN 技术资料 PDF,问的第一个问题是「这东西能不能直接拿来用」。大语言模型这个圈子里,技术资料最常见的命运是被收藏、被转发、被在群里夸一句「写得挺全」,然后躺在硬盘里再没打开过。这份 QWEN 报告不太一样:它把预训练数据的清洗管线、分词器的压缩率对比、SFT 与 RLHF 的数据配比、上下文扩展的做法,全都写成了可以照着算、照着配的参数,而不是只给结论。对做人工智能应用落地的人来说,它更像一份选型说明书加复现清单——你能从中读出「7B 和 14B 差在哪」「chat 模型为什么不能拿来干抽取任务」「长上下文为什么改了配置还是崩」。下面按我拆这份资料的顺序,把能直接抄的部分挑出来。

2. 把报告读薄:QWEN 的四条模型线与预训练管线

2.1 base、chat、code、math 四条线,选错一条白干半个月

报告开头那张模型谱系图信息密度很高,值得先盯三分钟。QWEN 系列不是一个模型,而是四条并行的产品线,共用同一批 base 权重:

线代表模型训练路径典型用途
通用基座QWEN(7B / 14B)纯预训练,3 万亿 token继续预训练、领域增量训练、自己做对齐
通用对话QWEN-CHATbase → SFT → RLHF问答、写作、工具调用、Agent
代码CODE-QWEN / CODE-QWEN-CHAT代码语料继续预训练 → SFT代码生成、调试、解释
数学MATH-QWEN-CHAT数学语料继续预训练 → SFT小学到竞赛级应用题、推理链

这张表最容易被忽略的一列是「训练路径」。我见过太多人拿 QWEN-CHAT 去做结构化信息抽取,然后抱怨输出格式飘、爱加解释性废话。原因不玄学:chat 模型经过 SFT 和 RLHF,被优化成「像人一样回答」,它的目标函数里根本没有「严格只输出 JSON」这一项。要做稳定抽取、分类、打标,正确做法是拿 base 模型自己灌几百条样本做 SFT,或者在 chat 模型上再补一轮格式约束的微调。反过来,要做多轮工具调用和规划,base 模型也不合适,它没学过对话轮次和工具调用的特殊 token。

CODE-QWEN 和 MATH-QWEN 的存在说明了一件事:通用语料和垂直语料的分布差异,靠 SFT 阶段补是补不回来的,必须在预训练阶段就掺进去。报告里 CODE-QWEN 是在代码语料上继续预训练后再做 SFT,MATH-QWEN-CHAT 同理。这个顺序别搞反——先 SFT 再灌领域语料,前面的对齐会被冲掉,行话叫灾难性遗忘,血泪经验是冲完之后模型连话都不会好好说了。

参数规模上,开源出来的主力是 7B 和 14B 两档。7B 适合单卡验证和边缘部署,14B 是效果和成本比较平衡的一档。选择逻辑不该是「越大越好」,而是先算清楚你的并发量、单次请求可接受的延迟、以及显存预算,再倒推。14B 在 fp16 下光权重就 28GB,加上 KV cache,一张 40GB 卡跑单并发刚好,跑多并发就得量化或者上多卡。

2.2 3 万亿 token 的数据管线:去重、打分、上采样三步不能省

报告里预训练数据那一节写得很实在,值钱的是流程而不是数字。整个管线可以拆成五步,每一步都能自己复现:

第一步,从公开网页数据里抽正文。HTML 解析掉导航、广告、页脚,留下主体文本。这一步的坑在于编码和乱码,中文站点尤其多,抽完不做编码归一化,后面语言识别会误判。

第二步,语言识别打标。报告说数据是多语言的,中英占大头。实际做的时候不要只留中英,小语种样本对分词器的多语言压缩率是有正向作用的,报告里专门测了十几种语言的压缩率,说明这块他们是在意的。

第三步,去重。分两级:规范化之后的精确匹配去重,以及用 MinHash + LSH 做模糊去重。模糊去重是真正吃资源的部分,也是最容易被跳过的一步。跳过它的后果是模型在重复样本上过拟合,验证集 loss 掉得好看,实际泛化一塌糊涂。

第四步,质量打分。报告里用了多个模型给内容打分:语言模型打分、文本质量打分、有害内容识别。规则过滤加模型打分组合使用,再叠加人工抽样复核。这一步的工程含义是——你需要一套可以离线批量跑的推理管线,几亿条样本打分不是小活。

第五步,按来源上采样。高质量来源(百科、书籍、部分代码库)提高采样权重,让模型在有限 token 预算内多见好数据。

模糊去重这段可以直接抄,用 datasketch 就够:

from datasketch import MinHash, MinHashLSH import re def shingles(text: str, k: int = 5) -> set: # 去掉所有空白后再切 shingle,避免排版差异影响相似度 text = re.sub(r"\s+", "", text) return {text[i:i + k] for i in range(max(len(text) - k + 1, 1))} def build_minhash(text: str, num_perm: int = 128) -> MinHash: m = MinHash(num_perm=num_perm) for s in shingles(text): m.update(s.encode("utf-8")) return m # threshold 是 Jaccard 相似度阈值,0.8 表示八成重合就算重复 lsh = MinHashLSH(threshold=0.8, num_perm=128) docs = [...] # 你的语料,先按长度过滤掉过短的 for i, doc in enumerate(docs): mh = build_minhash(doc) if lsh.query(mh): # 命中已有桶,判定为近似重复 continue lsh.insert(str(i), mh) # 未命中则入桶

几个参数的含义得说清楚。num_perm是 MinHash 的置换次数,128 是精度和内存的折中,调到 256 精度更高但内存翻倍,一般语料量级下 128 够用。threshold决定多像才算重复,0.8 是经验值,做网页去重可以放到 0.7 更狠一些,做论文去重要收紧到 0.9,否则同一篇论文的不同版本会被误杀。k是 shingle 长度,中文按字符切,5 比较合适;英文按词切的话 5 到 9 都行。注意这段代码是单机内存版,上到十亿级样本要换分布式 LSH 或者先做分桶再局部去重。

2.3 分词器压缩率:那张图比一堆 benchmark 分数更值得看

报告里有一张编码压缩率的图,横轴是语言,纵轴是压缩率,基准是支持 100 种语言的多语言分词器,值设为 1。参与对比的有若干同尺寸开源模型,QWEN 在中英和代码上的压缩率明显更高。

这张图为什么重要?压缩率高意味着同样一段内容,切出来的 token 更少。三个直接后果:第一,同样的上下文窗口能塞进更多实际内容,做长文档问答时体感差别很大;第二,同样的 token 预算能训更多真实文本,训练效率更高;第三,推理时的计费和延迟都更低,尤其是按 token 计费的场景。

中文场景下这个差异会被放大。很多以英文语料为主训出来的分词器,一个常用汉字可能要拆成两到三个 token,一段 1000 字的中文文档轻松吃掉 2000 多个 token。选型阶段如果你手头有中文长文档场景,压缩率应该排在 benchmark 分数前面考虑。

自己测一遍不难,二十行代码的事:

from transformers import AutoTokenizer SAMPLES = { "zh": "大型语言模型在预训练阶段需要处理海量多语言语料。", "en": "Large language models require massive multilingual corpora during pretraining.", "code": "def dedup(docs):\n return list({d for d in docs})", } def compression_ratio(model_id: str, text: str) -> float: tok = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True) n_tokens = len(tok.encode(text)) # 用「字符数 / token 数」作为每 token 承载的信息量 return len(text) / n_tokens for lang, text in SAMPLES.items(): print(lang, round(compression_ratio("your-model-path", text), 2))

需要提醒的是,别拿不同分词器切出来的 token 数直接对比不同模型的上下文利用率,还要看模型本身对长上下文的实际召回能力——窗口开得大不等于中间的内容它真的看得见,这一点在第 3 章会展开。

3. 参数落地:显存账、上下文扩展与对话模板

3.1 7B 和 14B 的三本显存账,算错一本就爆

选型时最容易翻车的地方是把「能推理」当成「能训练」。同一张卡,推理、LoRA 微调、全参微调是三本完全不同的账。下面是按 fp16 粗算的量级,具体数值会随框架、并行策略、序列长度浮动,但数量级不会骗人:

场景7B14B关键变量
纯推理 fp16约 14GB约 28GB权重 + KV cache
纯推理 int8约 7GB约 14GB量化损失
纯推理 int4约 4GB约 8GB量化损失更大
LoRA 微调单卡 24GB 起单卡 40GB 起序列长度、batch、是否梯度检查点
全参微调8 卡 80GB + ZeRO8 卡 80GB + ZeRO优化器状态占大头

全参微调为什么这么吃显存?一个 7B 模型 fp16 权重 14GB,梯度又是 14GB,Adam 优化器还要存一阶二阶动量和 fp32 主权重,加起来轻松过 100GB。所以真正做全参微调基本都要 ZeRO-3 或 FSDP 把状态切到多卡上,单机八卡 80GB 是起步配置。做领域适配我更推荐 LoRA,几百条到几万条样本的量级,LoRA 的效果和全参微调差不了多少,成本差一个数量级。

KV cache 这笔账单独说。推理时的显存占用 = 权重 + KV cache,后者随并发数和序列长度线性增长。估算公式是2 × 层数 × 隐层维度 × 序列长度 × batch × 字节数,7B 模型 32 层、隐层 4096,单条 8K 上下文在 fp16 下 KV cache 就要 4GB 上下。这也是为什么长上下文场景明明权重塞得下,一上并发就 OOM——爆的是 cache 不是权重。常见的缓解手段是 PagedAttention 一类的分页管理,以及限制单请求最大长度。

3.2 上下文扩展:只改配置不重新训练,等于没改

报告里专门有一节讲上下文长度扩展,这块是很多人踩坑的重灾区。常见做法是基于旋转位置编码做插值或者调整基频,把模型在短上下文上学到的位置关系拉伸到更长范围,然后在长文本语料上继续预训练一小段,最后在 SFT 阶段混入长样本。

关键点在于:位置编码的改动必须配训练。只把配置里的最大长度从 2K 改到 8K,模型不会凭空学会看第 5K 个 token,它只是被允许接收更长的输入。表现出来就是——短问题回答正常,一旦关键信息落在文档中段,模型开始答非所问,而且答得很自信,这种错误最难查。

配置层面大概是这个形态:

from transformers import AutoConfig cfg = AutoConfig.from_pretrained("your-base-model") # 位置插值:把原始训练长度等比例拉伸,scale 通常等于 新长度 / 原长度 cfg.rope_scaling = { "type": "linear", # 也可以选动态 NTK 一类方案 "factor": 4.0, # 2K -> 8K 时取 4.0 } cfg.max_position_embeddings = 8192 cfg.save_pretrained("./base-8k-init")

factor要和目标长度严格对应,2K 扩到 8K 是 4 倍,写成 8 就把位置关系拉坏了。type的选择上,线性插值实现简单、对短文本性能损失小;动态方案在超长文本上表现更稳但实现复杂,还要改注意力计算。不管选哪种,后面都得跟一步继续预训练,数据里长文档的比例要够,光靠短样本拼接出来的「伪长文本」学不到跨段落的依赖。

还有一个 SFT 阶段的细节:长上下文能力最终是在对话形态下被使用的,所以 SFT 数据里必须有长文档问答、长文档摘要这类样本,长度分布要覆盖到你目标窗口的 80% 以上。只在预训练阶段扩窗口、SFT 全是短样本,最后的 chat 模型长上下文能力会明显退化。

3.3 对话模板和特殊 token:格式错一位,训了等于白训

chat 模型的行为有很大一部分是被对话模板和特殊 token 定义的。报告附录里给了 QWEN-CHAT 的数据格式,属于带角色标记的 ChatML 风格。自己构造 SFT 数据时,模板必须和基座预期的完全一致,包括换行符的位置。

一个典型的样本长这样:

{ "conversations": [ {"from": "user", "value": "把下面这段日志里的错误码提取成 JSON"}, {"from": "assistant", "value": "{\"code\": \"E1024\", \"level\": \"error\"}"} ] }

渲染成模型输入时,user 轮加用户角色标记,assistant 轮加助手角色标记,整段以结束标记收尾。这里有两个高频错误:一是自己手写模板时多一个空格或者少一个换行,模型学到的是错位的边界,输出会莫名其妙地带上前缀;二是把 system 提示当成普通 user 内容拼进去,结果模型分不清指令和问题,多轮之后开始混淆角色。

我一般会在正式训练前做一次「模板回读」验证:拿一条训练样本按模板渲染成字符串,再用同一个分词器编码解码回来,肉眼比对是否和数据原文一致。这一步只花五分钟,能省掉一次八卡跑六个小时然后发现 loss 不降的悲剧。

4. 对齐三段式:SFT、Reward Model、RLHF 的排布与取舍

4.1 SFT:数据配比比学习率重要十倍

报告里 SFT 数据覆盖了几类:任务执行、闲聊对话、工具调用、Agent 行为、安全对齐。这个分类方式值得抄,因为它对应的是能力维度而不是数据来源。自己构造 SFT 集时,我一般按能力维度分桶,每桶定一个目标比例,再往里填样本,而不是先把手里所有数据混一起。

比例怎么定?看你的目标场景。做企业内部的工具调用助手,工具调用和任务执行的样本就该占到六成以上;做通用问答,闲聊和知识问答的比例要提上来;做面向终端用户的产品,安全样本不能省,比例低到 5% 也比没有强,因为安全行为的遗忘速度比能力提升速度快。

训练超参上,SFT 阶段的学习率通常比预训练低一到两个数量级,epoch 数控制在 3 以内。超过 3 轮之后模型开始背训练集,表现为在训练样本上答得完美,换个问法就崩。判断过拟合不要只看 loss,要看模型对同义改写的鲁棒性——把问题换个说法再问一遍,答案质量掉得厉害就是过拟合了。

数据量级上,几千条高质量样本能做出明显效果,几万条能覆盖大部分常见场景。真正拉开差距的是数据质量而不是数量:同一条指令配一个模糊、含糊的答案,训进去就是负资产。清洗时我习惯按答案长度做一遍分布检查,长度异常短或者异常长的样本人工过一遍,这一步能捞出一批脏数据。

4.2 Reward Model:偏好数据的构造比模型结构更关键

RLHF 的第一段是训奖励模型。做法是给同一个 prompt 采多条回答,人工或者强模型标注哪条更好,训一个回归模型去拟合「人类更喜欢哪条」这个偏好。报告里用的是成对比较的思路,损失函数基于 Bradley-Terry 假设,本质是让好回答的得分比差回答高出越多越好。

偏好数据的构造有几个实操要点。一是同一个 prompt 下的多条回答要有明显的质量梯度,如果两条回答半斤八两,标注出来的偏好就是噪声。二是要控制长度偏置——标注员天然偏爱长回答,如果偏好数据里长回答系统性胜出,训出来的奖励模型就会奖励啰嗦,后面 PPO 阶段模型会疯狂堆字数来骗分。缓解办法是在标注指引里明确「简洁且正确优于冗长」,并在数据里刻意放一些短而精的胜出样本。

奖励模型的规模一般比策略模型小一档,7B 的策略模型配 1.5B 到 7B 的奖励模型都有人用。训练时要注意的是训练集和验证集按 prompt 切分而不是按样本切分,同一个 prompt 的不同回答不能跨集,否则验证指标会虚高。

4.3 RLHF:PPO 阶段最容易翻车的三个地方

PPO 这一段是整个流水线里最难调的部分,报告里提到用 RLHF 之后的 chat 模型在人工评测里竞争力很强,但工程上复现的难度远高于 SFT。

第一个是 KL 惩罚系数。这个系数约束策略模型不要偏离 SFT 模型太远,设得太小,模型会放飞自我去骗奖励模型,输出变得怪异;设得太大,等于白训,模型几乎不动。常见起点是 0.01 到 0.05,然后看 KL 散度的实际曲线来调,散度如果一路飙高说明约束太松。

第二个是奖励作弊。奖励模型是策略模型的对偶,策略模型会找到奖励模型的盲区。典型表现是回答开始堆砌套话、加粗、列一堆用不上的要点,人类看着烦但奖励模型给高分。发现这个现象的唯一办法是持续人工抽检 PPO 训练中的输出,不能只盯奖励曲线。

第三个是长度爆炸。前面提到的长度偏置会在 PPO 阶段被放大,几轮之后回答长度翻倍但信息量没变。缓解手段包括在奖励里显式加长度惩罚,以及在 PPO 训练中监控输出长度分布,超过阈值就回滚 checkpoint。

这一段我没法给出「照抄就能跑」的完整脚本,因为 PPO 的超参强依赖你的奖励模型和 SFT 基座,别人调好的参数搬到你这大概率不灵。合理预期是先跑一个极小的实验——几百条 prompt、单卡、少量步数——把整条链路跑通,看奖励曲线和 KL 曲线形态对不对,再放大规模。

5. 避坑与排查:五个真实翻车现场

5.1 训练侧的三次翻车

现象一:SFT loss 平滑下降,但模型输出全是模板化的客套话。原因是数据里 assistant 侧的回答长度分布过于集中,大量样本开头是同一句「好的,我来帮你……」,模型学到了这个开头的高频模式,把它当成了万能解。解决办法是清洗时统计开头若干 token 的重复率,对高频开头做下采样或者改写,同时在训练时对重复 n-gram 加一点惩罚。

现象二:LoRA 微调后模型在领域任务上变强,但通用能力断崖下跌。原因是 LoRA 的秩设得太小、训练步数太多,适配器把基座的行为压过去了。秩从 8 提到 32 到 64,步数砍一半,同时在训练集里掺 10% 到 20% 的通用指令数据做正则,通常能缓过来。这个配比不是玄学,是让适配器在学新任务的同时被拉住不要忘本。

现象三:多卡训练吞吐上不去,GPU 利用率在 30% 上下晃。八成是数据加载成了瓶颈。检查 dataloader 的 worker 数、是否在训练时做重分词、样本长度分布是否极度不均导致 padding 浪费。我的习惯是先把样本按长度排序做长度分组,让同一 batch 内长度接近,padding 浪费能砍掉一大半;再确认分词是在预处理阶段离线做完的,而不是训练时现算。

5.2 推理与评测侧的两次翻车

现象四:长文档问答,答案总是漏掉文档中段的内容。先别怀疑模型,检查两件事。一是位置编码扩展之后有没有做继续训练,只改配置的情况最常见;二是推理框架的最大长度参数和模型的max_position_embeddings是否一致,不一致时框架会静默截断。排除这两条之后,再看检索环节是不是把关键段落切碎了——分块大小和重叠窗口的设置对结果影响很大,长文档场景下块与块之间留 10% 到 15% 重叠比较稳妥。

现象五:同一个 prompt 反复请求,输出质量时好时坏。先看采样参数,温度高于 0.8 时输出方差本来就大,做评测必须固定 seed 或者把温度压到 0.1 以下。如果低温下仍然飘,检查是不是在跑量化版本——int4 量化在某些指令跟随任务上退化明显,尤其是需要严格格式输出的场景。另外 batch 推理时不同请求的 padding 方式有时会影响结果,做对比评测要保证单条推理。

6. 用一套小评测确认你复现的模型真的能用

训练跑完、loss 曲线漂亮,不代表模型能上线。我吃过一次亏:SFT 训完看验证 loss 降了三成,直接打包给业务方,结果对方一测全是问题——格式对不上、拒答率飙升、回答长度翻倍。后来复盘发现验证集和训练集同分布,压根没测到真实场景。从那以后我每次交付前都强制走一遍三层验证。

第一层是能力回归,用固定的 prompt 集覆盖目标场景的典型任务,每个任务二十到五十条,跑完人工看一遍。别用公开 benchmark 当唯一标准,它和你的业务分布差得远。

第二层是格式合规率,机器统计。要 JSON 的场景就统计可解析率,要固定字段的就统计字段齐全率。这一层必须自动化,因为它是回归测试里最容易退化的部分。

第三层是对比评测。拿新模型和基线模型在同一个 prompt 集上各跑一遍,两两比较胜率,而不是给绝对分。绝对分主观性太强,同一个回答今天打 4 分明天打 3 分很正常,成对比较稳定得多。

import json, random def pairwise_win_rate(base_outputs, new_outputs, judges): """judges 是标注结果列表,1 表示新模型更好,0 表示基线更好,0.5 表示持平""" wins = sum(judges) return wins / len(judges) # 评测集按 prompt 切分,确保同一个 prompt 的多条回答不会跨集 with open("eval_prompts.jsonl", encoding="utf-8") as f: prompts = [json.loads(line) for line in f] random.seed(42) # 固定抽样,保证每次评测可比 sample = random.sample(prompts, min(200, len(prompts)))

这段里两个参数值得强调。random.seed必须固定,否则每次抽到的样本不同,指标波动会被误读成模型变化。样本量 200 是人工评测的下限,少于这个数胜率的置信区间宽到没有参考价值,机器评测可以放到上千条。

还有一个容易忽略的指标是拒答率。模型在安全对齐之后,遇到边界模糊的问题会倾向于拒答,业务场景下拒答率过高等于不可用。评测集里要专门放一批「应该回答」的边界样本,统计拒答比例,这个数比准确率更早暴露问题。

最后一句经验:任何一次改动,哪怕只是换了个量化版本,都把这套评测完整跑一遍,别信「只改了一点点」。我见过太多「只改了一点点」最后变成线上事故的案例。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询