← 返回深度解读总览

《Language Models are Unsupervised Multitask Learners》深度解读报告

GPT-2 · OpenAI 技术报告 · 2019 年 2 月 · Radford*, Wu*, Child, Luan, Amodei**, Sutskever**
数据依据:00-源数据提取.md(PDF 全文 pymupdf 解析,24 页)。全部数字与源数据一致;标注「(推断)」处为分析者推理补充。CBT 两处成绩的 Table 3 / 正文微差按稿内双记录处理。

摘要

本文解读 OpenAI 2019 年 2 月发布的 GPT-2 技术报告。核心论断只有一句话:语言建模本身就是一个无监督的多任务学习框架——当语言建模目标 p(x)=∏p(sₙ|s₁..sₙ₋₁) 与有监督任务的 p(output|input) 在「输出是输入序列的子集」条件下共享全局最优解时,一个容量足够大的语言模型在足够的自然语料上训练,会自发学会执行问答、翻译、摘要、阅读理解等任务,无需任何任务专属架构或标注数据。为验证该假设,作者构建了以 Reddit 外链为质量代理信号的 40 GB WebText 语料,将参数量推至原 GPT 的 10 倍以上(1542M),并以纯零样本方式在 8 个语言建模基准中的 7 个刷新当时 SOTA(WikiText-103 困惑率 17.48 vs 18.3;LAMBADA 困惑率 8.63 vs 99.8),在 Winograd Schema 上达 70.70%、CoQA 上达 55 F1,且发现零样本性能随参数量呈 log-linear 增长。这篇论文是「规模假设」的第一份系统性实证,其提示诱导任务行为的做法直接孕育了 GPT-3 的 in-context learning。本报告按「问题—概念—方法—证据—批判—启示」六层结构逐层拆解。

一、问题定位:监督学习的标注瓶颈与「多任务」的乌托邦

1.1 论文要解决的问题

2019 年初的 NLP 处于监督学习全盛期:BERT 刚刚横扫 GLUE,但每个下游任务都需要数千到数万条人工标注样本。论文开篇指出这一范式的结构性缺陷——当前系统是狭窄专家(narrow experts):在一个任务上训练只能做这一个任务,泛化脆弱。而人类层面的观察是:绝大多数人类是在无监督数据上学习语言的,执行具体任务所需的监督信号极其有限。

作者的策略不是发明新的监督算法,而是追问一个更根本的问题:能否让「学习执行任务」这件事本身就成为无监督的?如果语言建模的目标函数在数学上已蕴含「根据上下文预测缺失部分」的能力,那么问答(预测答案段)、翻译(预测译文段)、摘要(预测摘要段)都只是它的特例——只要把任务表达成自然语言序列的一部分,一个足够强的条件文本生成器就应当能零样本完成它们。

1.2 多任务学习视角下的形式化

论文将 multitask learning 形式化为在「任务 + 输入」联合分布上的条件估计 p(output|input; task)。传统做法显式加载任务模块;本文的关键转译是:当输出是输入序列的子集时,语言建模的全局最优解就是多任务学习的全局最优解。例如「10 月 7 日,政府宣布……」这类序列中,下一词预测隐含了 QA、指代消解、实体识别等多种子任务的压力。任务条件化不需要架构级编码器,只需用自然语言序列表达——如三元组 (translate to french, english text, french text)。(推断)这是全文最重要的一步棋:它把「任务」从系统组件降格为「文本的一种写法」,为此后整个 prompt 工程范式奠定了理论基础。

1.3 为什么此前无人做到:容量、数据与评测协议的三重缺口

论文在谱系中的位置十分清晰:GPT-1 已证明生成式预训练 + 有监督微调的有效性,但仍需微调;ELMo/BERT 提供了好的表征,仍要接任务头训练。三者共同的潜台词是「预训练学到表征,任务靠微调激活」。本文的反命题是:任务行为可以直接从预训练模型中被「问」出来。要让反命题可检验,需同时补齐三个缺口:

一句话小结:把「标注瓶颈」重新表述为「目标函数等价性未被兑现」——语言建模的损失函数天然是多任务的,缺的只是容量、干净数据和敢不做微调的勇气。

二、概念内核:五个核心概念逐一定义

2.1 无监督多任务学习假设

定义:语言建模目标 p(x)=∏p(sₙ|s₁..sₙ₋₁) 与有监督目标 p(output|input) 在「输出即序列子集」时全局最优解一致,故足够容量的语言模型在自然语料上会自发学会执行任务。

拆解:「全局最优」四字是理解全文的关键限定。它并不声称任意训出的 LM 都会做题,而是说两个目标的最优解重合——因此理论上存在一条只靠扩大模型与数据的路径通往多任务能力。(推断)这是一个精心构造的「不可证伪但可逼近」的命题:即使零样本成绩不佳,也可归因于容量或数据不足而非假设错误;而 Figure 1 的 log-linear 缩放曲线恰好提供了「正在逼近」的证据。这个论证结构后来演化为整个 scaling law 叙事的模板。

2.2 任务条件化(Task Conditioning as Sequence)

定义:用自然语言序列表达任务条件,如 (translate to french, …)、TL;DR: 提示,无需架构级任务编码器。

拆解:这一概念把「任务」从 API 参数变成了文本内容。摘要用 TL;DR 触发、翻译用对齐格式触发、CoQA 用 document/history/"A:" 三段式条件化。它是 GPT-3 few-shot prompt 的直系前身,也是今天一切指令跟随模型的远祖。区别在于:GPT-2 的提示是评测者手工设计的外部协议,模型并未被专门训练去理解指令——这解释了为何同一任务换一种措辞成绩会剧烈波动(摘要去掉提示降 6.4 分)。

2.3 WebText:以人为过滤器的语料构建哲学

定义:放弃 Common Crawl,改用 Reddit 出站外链作为采集源,以「至少 3 karma」作为人工筛选的质量代理信号,最终得约 8M 文档 / 40 GB 文本(2017-12 截止版本)。

拆解:45M 条 Reddit 外链经 Dragnet + Newspaper 组合抽取器提取正文、去重清洗后收缩为约 8M 文档——采集量到留存量的比例本身就是一层数据质量漏斗。最激进的决定是移除全部 Wikipedia 文档(0 条),避免与其他基准的训练/测试重叠造成污染混淆。(推断)这让 WikiText 系列上的零样本成绩更具说服力,但也使百科体知识覆盖依赖间接来源。法语仅约 10 MB(比无监督 MT 常用单语法语语料小约 500 倍)这一测量值,提前锁定了翻译任务失利的命运——数据分布决定能力边界。

2.4 Byte-level BPE:无预处理失配的表示层

定义:基词表仅 256(字节级)的字节对编码,最终词表 50,257;禁止跨字符类别合并(空格除外)。

拆解:字节级的意义在于全域覆盖:模型能给任意 Unicode 字符串赋概率,不会出现 OOV 或未知符号,可在任何基准上评测而免于分词方案不一致带来的预处理失配。禁止跨字符类别合并则是工程取舍:防止 dog、dog.、dog! 各占一个词表槽位浪费容量。(推断)这一选择当时是为了零样本评测协议的自洽——八套基准各有分词传统,唯有字节级才能一套模型通吃;后来它成为开源大模型的标配,证明了长期价值,代价是序列更长、注意力开销更大。

2.5 零样本评测协议

定义:不经任何任务微调,直接用条件概率对候选答案打分,或用 greedy/top-k 采样生成,再以任务原生指标评测。

拆解:分类任务走「打分路线」(LAMBADA/CBT/Winograd);生成任务走「采样路线」(摘要用 TL;DR 提示 + top-k k=2 采样取前 3 句、翻译用对齐格式、QA 用 greedy 解码)。(推断)这条协议线是最容易被低估的方法学贡献:它定义了此后五年 zero-shot/few-shot evaluation 的标准形态,也埋下了「评测结果依赖提示措辞」这一延续至今的方法论难题。

一句话小结:五个概念构成一条完整链条——多任务假设给出理论承诺、任务条件化给出执行接口、WebText 解决数据供给、Byte-level BPE 解决表示统一、零样本协议解决验证方式。

三、方法拆解:数据—表示—架构的三位一体工程

3.1 数据侧:WebText 的采集与清洗管线

这套管线的深层逻辑是用社会信号替代语义质量判断:不判断文本「写得好不好」,而判断「是否被足够多的真人自愿点击和点赞」。(推断)代价是引入 Reddit 用户群体的分布偏置——英语主导、技术宅倾向、口语化占比高,这与后文 PTB/WikiText 上优势最大、法语翻译惨败的现象互为因果。

3.2 表示侧:Byte-level BPE 的实现细节

从 256 字节基出发做 BPE 合并至 50,257 个 token(含特殊 token)。合并规则禁止跨字符类别混合(空格豁免),使词形变化共享基础 token,提高词表利用率。(推断)字节级回退保证任何输入都能被编码,让「同一模型跑 8 个不同领域的 LM 基准」成为可能,也让 de-tokenizer(可逆去分词器)的后处理得以实施——后者单独带来 2.5–5 PPL 提升,说明分词边界与评测口径的匹配对成绩影响可观。

3.3 架构侧:Transformer 四档规格与三处改动

参数量Layersd_model备注
117M12768≈ 原 GPT
345M241024≈ BERT-Large
762M361280—
1542M481600GPT-2,参数量为 GPT 的 >10 倍

统一配置:词表 50,257;上下文从 512 升至 1024 tokens;batch size 512;学习率按 5% held-out WebText 困惑率手工调参。相对 GPT-1 的三处架构改动:

  1. LayerNorm 移至子块输入(pre-LN,类比 pre-activation ResNet),稳定深网络训练;
  2. 最后一个 self-attention 块之后再加一层 LayerNorm;
  3. 残差层初始化权重按 1/√N 缩放(N 为残差层数),防深栈残差流方差爆炸。

(推断)这三处都是「48 层能不能训稳」的保命设计,pre-LN 后来几乎成为所有深层 Transformer 的默认选择。一个常被忽略的事实:论文明确记录所有四个模型在截稿时均欠拟合(underfit)WebText——训练未收敛。这既是诚实披露也是伏笔:零样本成绩是能力的下界,为后续继续训练/放大留出叙事空间。

3.4 训练与评测的一体化设计

训练目标是标准语言建模,没有任何任务相关损失项;评测完全外置。这种「训练侧极简、评测侧精巧」的不对称设计正是论点本身的体现——如果任务能力真来自预训练,那么训练代码里就不应该有任何任务的痕迹。

一句话小结:三根柱子撑一个赌注——WebText 保证数据质量与多样性、Byte-level BPE 保证表示全覆盖、pre-LN 深架构保证 1542M 训得动且远未收敛;训练代码不留任务痕迹是对假设最严格的自我约束。

四、证据链:从 7/8 破纪录到记忆化检验的四层实证

4.1 第一层:八个语言建模基准(Table 3,1542M 行)

数据集指标GPT-2 (1542M)当时 SOTA判定
LAMBADAPPL8.6399.8★数量级跃迁
LAMBADAACC63.24%(停用词过滤版;朴素版 52.66%,此前 LM 最佳 19%)~59%★超 SOTA
CBT-CNACC93.30%*(正文记 93.3%)85.7★新 SOTA
CBT-NEACC89.05%*(正文记 89.1%)82.3★新 SOTA
WikiText-2PPL18.3446.54★大幅领先
PTBPPL35.7646.54★大幅领先
enwik8BPB0.930.99★领先
text8BPC0.981.08★领先
WikiText-103PPL17.4818.3★领先
One Billion WordPPL42.1621.8✗唯一失利
* CBT 双口径说明:Table 3 记 93.30%(CN)/ 89.05%(NE),论文正文分别记 93.3% / 89.1%,为四舍五入口径差异,源数据双记录并存;任一口径均较此前 SOTA 有约 6–7 点大幅提升。

逐条解读:

  1. LAMBADA 是质变证据。困惑率从 99.8 降到 8.63 是超过 11 倍的数量级改善;该测试要求读完全篇后预测句末词,专测长程依赖。作者进一步诊断错误模式:多数错误是「合法续写但不是句末词」,于是加停用词过滤器模拟句末约束,准确率再涨至 63.24%。(推断)这说明模型内部已具备全篇语义追踪能力,差的只是「知道现在是填空题」的任务感知。
  2. PTB 与 WikiText-2 收益最大的结构性原因:两者仅有 1–2M 训练 token,最能凸显外部知识迁移的价值——本地数据根本不足以支撑 35.76 的困惑率。
  3. 1BW 失利是最诚实的一条数据。作者归因于二者叠加:句子级乱序预处理摧毁长程结构(与 GPT-2 最强的长程能力正面冲突)、且该数据集最大、SOTA 是充分调优的专用系统。(推断)42.16 vs 21.8 的落差反而强化可信度——它划清了「零样本通才」与「领域专才」的边界。

4.2 第二层:六个下游任务的零样本表现

任务成绩对比基线
CoQA 阅读理解55 F1(greedy 解码 + document/history/"A:" 条件化)匹配或超过 4 基线中的 3 个,且不用其训练用的 127,000+ 问答对
Winograd Schema70.70%(较 Trinh & Le 2018 提升 7%;数据集仅 273 例)前 SOTA ~63%
CNN/Daily Mail 摘要R-1/R-2/R-L = 29.34 / 8.27 / 26.58(R-AVG 21.40)接近经典神经基线,略胜随机 3 句(20.98);Bottom-Up Sum 为 32.75;去掉提示降 6.4 分
WMT-14 En→Fr5 BLEU差于词对词双语词典替换基线
WMT-14 Fr→En11.5 BLEU超过部分无监督 MT 基线,远低于最佳 33.5
Natural Questions4.1% exact match;最高置信 1% 问题准确率 63.1%;正确数为最小模型的 5.3 倍检索+抽取式混合系统在 30–50% 区间

解读:这张表呈清晰梯度——常识推理类(Winograd)超 SOTA,阅读理解类(CoQA)接近监督基线,生成类(摘要)勉强可用,知识密集类(NQ)远逊专用系统,跨语言类(翻译)因数据稀缺溃败。(推断)梯度本身就是「数据分布决定能力分布」的实证:Reddit 英语讨论覆盖常识与阅读场景最好、摘要体裁次之、事实知识受限于语料快照、法语句对几乎为零。Table 5 定性样例(Charles Darwin / Mark Shuttleworth / Aaron Rodgers,置信度 83.4%–45.2%)展示模型确实「记住」了世界事实,但 NQ 整体 4.1% 说明这种记忆无法可靠地按需调用。

4.3 第三层:容量的 log-linear 定律(Figure 1)

所有任务上,性能随 117M → 345M → 762M → 1542M 单调提升且近似 log-linear。最有力的单项证据来自 Natural Questions:最大模型答题正确数量是最小模型的 5.3 倍。作者据此断言:此类任务上「神经系统的落后主因是容量不足」。配合「所有模型仍欠拟合 WebText」的事实,构成对 scaling 方向的强论证——能力尚未饱和,继续加大规模将继续获益。(推断)Figure 1 是整篇论文传播度最高的图:它给出了可外推的直线,后来的 Kaplan 缩放定律与 GPT-3 都是沿这条直线走下去的结果。

4.4 第四层:泛化还是记忆?(§4,Bloom filter 分析)

针对「零样本成绩是否只是背下测试集」的质疑,作者用 Bloom filter 存入 WebText 训练集全部 8-gram(假阳率上限 10⁻⁸,先以 1M 随机串验证零误报),统计各基准测试集与训练集的重叠率。三项发现:

  1. 常见 LM 测试集与 WebText 平均重叠 3.2%(区间 1–6%),反而低于各数据集自身 train/test 重叠均值 5.9%(WikiText-103 测试集含训练集文章 ≥1.6%,One Billion Word 自重叠高达 13.2%);
  2. 剔除与训练集 8-gram 重叠的样本后,LAMBADA 仅从 8.6 → 8.7 PPL、63.2% → 62.9% ACC——重叠带来「小幅但一致」的收益,不改变结论;
  3. WebText 内部 held-out 曲线随模型增大同步改善(Figure 4),佐证模型在未见数据上同样进步,是欠拟合而非记忆化的特征。

(推断)此节的巧妙在于反守为攻:不仅洗清自己,还顺手指出现有基准自身的 train/test 重叠比 GPT-2 的「污染」更严重。当然,8-gram 重叠只能捕捉表面复制,无法检测语义级记忆——这一局限要到多年后 membership inference 研究成熟才被充分讨论。

一句话小结:证据体系呈金字塔形——塔尖是 7/8 破纪录与 LAMBADA 数量级跃迁,中层是六任务梯度与 5.3 倍容量效应,塔基是 Bloom filter 记忆化排除;三层合力支撑「零样本多任务能力真实存在且随容量增长」的主张。

五、批判性分析:自认局限、未披露项与独立疑点

5.1 作者自述局限的深层含义

  1. 摘要等任务「仍只是初步(rudimentary),距实用尚远」:生成摘要常聚焦文末内容或混淆细节(车祸车辆数、logo 在帽子上还是衣服上)。深层含义:任务条件化只教会模型「任务的表面格式」,尚未教会「任务的完成标准」——这正是后来 instruction tuning 要解决的问题。
  2. 阅读理解依赖简单检索启发式:who 类问题直接回文中人名。说明部分成绩可能由浅层策略驱动而非真正推理,(推断)273 例的 Winograd 小样本也有类似统计功效隐患。
  3. 许多实用任务上「GPT-2 不比随机好」:即便已评任务也需足量容量才能胜过平凡基线——罕见地承认了零样本能力的脆弱性。
  4. 单向表征的低效未被规模弥补:vs BERT 双向注意力的劣势被明确承认,微调潜力留待后续。(推断)这引发了当时「生成式 vs 判别式」之争,最终以生成式路线胜出告终。
  5. 所有模型截至发表仍欠拟合:训练时长不足,意味着所有成绩都是未收敛状态的下界。

5.2 未披露项清单

(推断)这份清单的合计效应:GPT-2 的零样本结果在发表时无法被独立复现。数据集不公开尤其关键——WebText 是论文的核心资产之一,其不可得性使「WebText 特有分布是否贡献了成绩」这一问题永久悬置。

5.3 独立观察到的五个疑点

① 零样本协议中含有相当份额的任务特定工程。摘要使用 TL;DR 提示 + top-k k=2 采样 + 取前 3 句的组合拳;LAMBADA 使用停用词过滤器;CoQA 用三段式条件化。这些都不是「纯粹的零样本」,而是评测者对每个任务手工设计的诱导方案。「去掉提示降 6.4 分」恰恰证明成绩高度依赖提示工程。(推断)公平地说,论文从未声称这些协议是自动习得的,但标题容易让读者高估自动化程度;直到 GPT-3 才用 few-shot 把这部分工程转移到推理时的示例选择上。

② 「多任务」实为「多评测」。模型没有被训练去切换任务,也没有在任何意义上「学会」任务边界——所有任务行为都是从同一个 LM 目标里被动涌现的。严格地说,论文展示的是「一个模型通过不同提示可以表现出多种任务行为」,距离「掌握多种可调度技能」尚有距离。(推断)这个语义滑移无害于数据本身,但影响了对「多任务学习」一词的使用规范。

③ 翻译失利暴露了假设的边界条件。Fr→En 仅 11.5 BLEU(对比 Artetxe et al. 2019 的 33.5),En→Fr 甚至只有 5 BLEU、差于词对词词典基线。根源清楚:WebText 法语仅约 10 MB,比标准单语语料小 500 倍。这印证假设的隐含前提——任务必须在其训练分布中有足够的「隐式监督密度」。(推断)换言之,「语言模型是无监督多任务学习者」应改写为「语言模型是其训练数据所涵盖任务的无监督学习者」,普遍性声明被数据分布截断。

④ NQ 成绩与叙事之间的张力。一方面 4.1% exact match 远逊检索系统的 30–50%;另一方面最高置信 1% 问题上达 63.1%、答题正确数随容量涨 5.3 倍。作者读出「容量是主因」的希望叙事,但同样合理的数据解读是:闭卷参数记忆在开放域事实问答上存在原理性短板,容量增长无法替代检索。(推断)后续几年 RAG 路线的兴起事实上支持第二种解读,「参数化知识 vs 检索知识」的争论至今未决。

⑤ CBT 双口径与 de-tokenizer 加成的细节透明度。CBT 成绩在 Table 3 与正文间存在 93.30%/93.3%、89.05%/89.1% 的微差(本报告按源数据双记录处理,不影响结论);de-tokenizer 带 2.5–5 PPL 提升说明评测分数中包含与「能力」无关的口径校准成分。(推断)这类细节单点上无关宏旨,但提醒读者:跨论文比较 LM 成绩时分词/解码/后处理的每一环都可能引入 1–5 点浮动,当年如此,今天依然。

一句话小结:证据在其声明的范围内扎实(记忆化检验尤为出色),但标题的普适性宣言超出了数据支持的范围——任务覆盖受数据分布约束、零样本成绩掺杂提示工程、「多任务」更多是评测姿态而非习得能力;这些裂缝没有推翻论文,而是精确标记了 GPT-3 及其后继者需要补齐的位置。

六、启示与影响:从技术报告到范式转换的五年

6.1 五条可迁移的启示

  1. 目标函数的等价性论证优先于算法发明:本文没有发明新算法,而是论证「已有目标函数(LM)在最优解层面已蕴含多任务能力」,然后把资源全部投向容量与数据。「找对目标函数,剩下的交给规模」的思维模式是此后五年工业界的主导方法论。(推断)凡面临「要不要为每个任务设计模块」的场景,都可先问:现有目标的最优解是否已包含该任务?
  2. 数据质量的社会信号代理:用 Reddit karma 替代语义质量判断,是「以人为过滤器」的数据工程典范。它预示了后来的两条路线——人工标注的小而精(InstructGPT/LIMA 式)与社会信号的规模化利用。40 GB 干净数据胜过大若干倍的噪声爬取,这一经验在 "data quality > quantity" 共识确立之前就已写下。
  3. 提示即接口(prompt as interface):(translate to french, …)、TL;DR: 是现代提示工程的化石级起源。核心洞察——任务可以在推理时用自然语言声明而非训练时固化——重构了人机交互界面,也带来了新的失效模式(提示敏感性、注入攻击)。
  4. 缩放叙事的证据形态:log-linear 直线 + 「仍欠拟合」披露的组合,确立了「给一条外推曲线 + 声明未饱和」的论证模板。引用此模板时应记住第五章教训:外推置信度取决于曲线跨越的容量范围(此处仅 13 倍)与任务选择偏差。
  5. 负结果与边界条件的价值:1BW 失利、翻译溃败、NQ 落后三条负结果非但没有削弱论文,反而精准划定假设的适用边界,使其成为可改进的科学命题而非不可证伪的宣传。「把失败数据放在正文显著位置」的做法值得所有技术报告效仿。

6.2 历史坐标:GPT-2 在谱系中的直接遗产

(推断)回望 2019 年,这篇论文最重要的作用是把「规模能否产生智能」从哲学争论变成了工程议程。它给出的答案并不完美——任务覆盖受数据分布约束、成绩依赖提示工程、复现链条断裂——但它把正确的变量(容量、数据质量、评测协议)推上了主舞台,此后五年的大模型历史在很大程度上就是对这三个变量的持续优化。

总结

《Language Models are Unsupervised Multitask Learners》用一个极简的训练目标(纯语言建模)撬动了多任务能力的涌现:WebText 的「人为过滤器」哲学供给了 40 GB 高质量语料,Byte-level BPE 消除了表示层的预处理失配,pre-LN 深架构把参数推到 1542M 并保持欠拟合状态,最终在 8 个语言建模基准中 7 个零样本刷新 SOTA(LAMBADA 困惑率 99.8 → 8.63 的数量级跃迁最为耀眼),并在 Winograd(70.70%)、CoQA(55 F1)上逼近甚至超越监督系统,同时以 3.2% vs 5.9% 的重叠对照和 Bloom filter 检验回应了记忆化质疑。其局限同样清晰:翻译与开放域问答的溃败暴露了「任务能力受训练分布约束」的边界,零样本协议中的手工提示成分提示「无监督」标签需打折理解,WebText 不公开与算力不披露留下了永久的复现缺口。但正是这篇技术报告,把 log-linear 缩放曲线、提示即接口、数据质量优先三条主线推入了此后五年的产业主旋律——它是从「预训练+微调」时代通向「预训练+提示」时代的枢纽文献。

自检清单:UTF-8 编码,无替换字符 ✓|六层结构完整(摘要/问题定位/概念内核/方法拆解/证据链/批判性分析/启示与影响)✓|关键数字均高亮且与源数据一致(1542M / 40GB / 8.63 / 63.24% / 93.30%-89.05% 双口径 / 17.48 / 70.70% / 55 F1 / 4.1% / 3.2% vs 5.9% 等)✓|CBT 微差按稿内双记录处理并注明 ✓|推断处均标「(推断)」✓|div 开闭配平(容器 div.wrap 1 个,header/blockquote/table/footer 均为配对标签)✓|内联 CSS 单文件、无外部依赖 ✓