I·Infra Notes AI Infra 工程实践指南 ← 返回主博客
延伸笔记 / READING NOTES

技术论文 / 技术方案写作框架

技术论文与方案的写作方法

适用对象:新技术论文(paper)、技术方案(proposal / design doc)、项目总结报告。

核心主张:你给的四段式(瓶颈 → 问题 → 方法 → 结果)不是四个并列的章节,而是一条论证链。每一段的唯一职责是让下一段能够成立。判断一段写得好不好,标准不是「内容全不全」,而是「它有没有把接力棒交出去」。

两个必须补上的缺口:① 现有方案为什么不够(Gap)——夹在「问题」和「方法」之间;② 代价与边界——挂在「结果」上。缺了第一个,方法像是凭空冒出来的;缺了第二个,结果从科学结论退化成营销文案。


目录


一、四段式 ↔ 标准章节的映射

四段式是论证骨架,论文的标准章节是载体。同一段论证可能横跨好几节,也可能被拆到不同位置。理解映射关系,才不会出现「第一节讲了瓶颈,第四节又重讲一遍」的重复。

四段式 论文里的位置 技术方案里的位置
① 瓶颈 Abstract 第 1 句 · Introduction 1.1 · 部分 Background 摘要第 1 句 · 第 1 章 背景与瓶颈
② 问题 Abstract 第 2 句 · Introduction 1.2 · Problem Formulation 摘要第 2 句 · 第 2 章 目标与非目标
Gap Related Work(逐类否定)· Introduction 1.3 第 3 章 现有方案评估
③ 方法 Abstract 第 3 句 · Method(含设计取舍) 摘要第 3 句 · 第 4 章 技术方案
④ 结果 Abstract 第 4 句 · Evaluation 第 5 章 预期结果与验证方式
代价与边界 Limitations · Discussion 第 6 章 风险与对策 · 非目标
闭环 Evaluation 首段 + Conclusion 第 5 章 验收标准

一个立刻可用的技巧:Abstract 就是四段式各写一句。如果摘要写不顺,说明四段里有某一段你自己还没想清楚——摘要不顺是论证断裂的症状,不是文笔问题。


二、逐段拆解:唯一任务、要点、失败模式

① 瓶颈(Motivation)

唯一任务:让读者相信「这个问题值得解决」,并且相信你对它的理解是机制级的,不是表面级的。

必须回答的五个问题:

# 要点 反面示例 正面示例
1 现象:什么场景、什么负载、观察到什么 「推理很慢」 「8 请求 × 32 token 的短 prompt 场景下,prefill 吞吐只有 1280 tok/s」
2 量化:慢多少 / 贵多少 / 占多少 「性能不佳」 「TTFT 200 ms,是同类基线 SDPA 路径的 4 倍」
3 定位:瓶颈落在哪个环节 「attention 是瓶颈」 「profiler 显示 aten::_local_scalar_dense 出现 224 次,28 层 × 8 序列」
4 归因:为什么是这个环节(机制,不是相关性) 「发现 attention 很慢,所以优化 attention」 「每层每条序列都要 .item() 做 device→host 同步,把异步流水线打断」
5 时效性:为什么现在必须解决 (完全不提) 「上下文从 4K 涨到 128K,KV 容量从『够用』变成硬约束」

常见失败模式:

  • 只有形容词:「效率低」「难以满足需求」「存在瓶颈」——没有数字就没有瓶颈。
  • 只有相关性没有机制:观察到 attention 慢,就直接去优化 attention,但没解释为什么慢。审稿人会问「换个场景还成立吗」,你答不上来。
  • 瓶颈与方案错位:第 1 段讲的是显存不够,第 3 段解的是算力浪费。这是最致命的一种断裂,因为读者读完会不知道你到底解决了什么。

交接给第 2 段的东西:一个有名字、有量级、有归属的瓶颈。

句式模板:

  • 「在【场景】下,【某个量】随【某个变量】线性增长,导致【后果】;实测【指标】为【数值】,比【基线】差【倍数】。」
  • 「profiler 显示【某 kernel / 某操作】占【总时间 / 总带宽】的【X%】,根因是【机制解释】。」

② 问题定义(Problem Statement)

唯一任务:把一个模糊的「要加速」,变成一个可证伪的命题。

关键区分:瓶颈是现象,问题是命题。

表述 性质
瓶颈 「KV cache 的读带宽是瓶颈」 事实陈述,描述世界
问题 「在保持输出分布不变的前提下,能否把每 token 的 KV 字节数降到 1/2 以内,且端到端延迟不上升?」 可证伪命题,是你的承诺

很多人把①②合并成一段。分开写的价值在于:瓶颈是世界的状态(客观、可观测),问题是你的承诺(主观、有约束、有判据)。混在一起,读者无法区分「这是事实」还是「这是你的目标」,于是也无法判断你是否达成了目标。

必须回答的五个问题:

  1. 目标(Goal):优化哪个指标?方向?幅度?
  2. 约束(Constraints):不能牺牲什么?(精度、分布一致性、显存上界、硬件兼容、API 稳定性)
  3. 边界(Out of scope):明确不解决什么。
  4. 成功判据(Success criteria):什么算成功?给阈值。
  5. 难点(Why hard):难在哪?——这一条决定了你的方法是不是「显然的」。

常见失败模式:

  • 目标不可度量:「提升性能」「优化效率」——没有判据,第 4 段就无法自证。
  • 没有约束:那任何方案都能「解决」问题(把模型换小算不算解决?把 batch 降到 1 算不算?)。约束越清楚,第 3 段的取舍越有说服力。
  • 没有 out of scope:审稿人一定会用你没打算解决的问题来否定你。写清楚边界是保护自己,不是示弱。

交接给第 3 段的东西:一个有约束、有判据、有边界的命题。

句式模板:

  • 「我们的目标是:在【约束 A、B、C】下,把【指标】从【现状】改善到【目标】。我们不处理【X】。」
  • 「这个问题的难点在于【X】:【目标 1】与【约束 2】之间存在直接冲突。」

③ 方法(Approach)

唯一任务:让读者相信「这个方案是必然的」——给定①②的约束,它是被推出来的,而不是被想出来的。

必须回答的六个问题:

  1. Gap 先行:现有方案为什么不够?(见第四节)
  2. 核心洞察(Key insight):一句话说清「你看到了什么别人没看到的」。整个方法应该能被压缩成这一句。
  3. 设计:从洞察到机制,分成几个组件?每个组件对应①②里的哪一条约束?
  4. 取舍(Trade-off):为了达成目标,你放弃了什么?为什么这个取舍可接受?
  5. 为什么不是更简单的做法:直接回答「为什么不直接 ___?」
  6. 可复现性:关键参数、伪代码、实现细节。

常见失败模式:

  • 上来就讲实现细节:读者不知道为什么要这么设计,只能死记硬背。
  • 组件与约束没有映射:说了 5 个模块,但看不出哪个模块对应哪个约束——方法就变成了「功能罗列」。
  • 回避取舍:不写代价,审稿人会认为你没做实验、或者隐瞒了代价。

最强的一种写法:把方法写成「约束的必然推论」。

因为约束 A(不能改变输出分布)→ 不能做近似 → 必须精确重排; 因为约束 B(显存有上界)→ 不能物化 N×N → 必须分块; 分块 + 精确 → 必须用 online softmax 做跨块归约。 于是 FlashAttention 只有这一种形态。

这样写,方法就不再是「我们提出了一个巧妙的算法」,而是「在给定约束下唯一剩下的选择」。说服力完全不同。

交接给第 4 段的东西:一组可被独立验证的机制 + 明确的取舍声明。

句式模板:

  • 「关键洞察是【一句话】。基于这一点,我们设计【机制】,它把【量】从【原形态】变为【新形态】。」
  • 「这个设计放弃了【X】,代价是【Y】;我们接受它,因为【Z】。」

④ 结果(Evaluation)

唯一任务:用你自己在第 2 段定义的判据,证明命题成立;同时诚实地说出代价和适用区间。

必须回答的七个问题:

  1. 回到判据:逐条对应②的成功判据,不要换指标。
  2. 闭环到瓶颈:用①里同一个指标再测一遍。(最容易被忽略,也最有说服力)
  3. 基线选择:和谁比?为什么是它?要有强基线,不能只和自己改之前比。
  4. 消融(Ablation):每个组件贡献多少?去掉会怎样?
  5. 代价与边界:什么情况下你的方法不划算?给适用区间和降级策略。
  6. 失败实验:你试过但没成功的路径,以及原因。这一条极大提升可信度。
  7. 可复现性:硬件、模型、shape、模式、原始数据。

常见失败模式:

  • 只报最好的一组数(cherry-picking):挑最漂亮的 shape 和 batch,读者复现不出来。
  • 换了指标:②说要降延迟,④报的是吞吐。读者无法判断命题是否成立。
  • 没有代价声明:一旦有人复现出反例,整篇的可信度崩塌。
  • 用与目标不匹配的指标冒充质量指标:例如用「exact token agreement」这种自回归 rollout 的敏感指标,去论证「输出质量无损」——它测的是数值扰动被放大的程度,不是语言质量。

句式模板:

  • 「在【条件】下,【指标】从【原值】改善到【新值】(【倍数】),与第 2 段的判据一致。」
  • 「代价是【Y】:当【条件】时,本方法不如【基线】。适用区间是【Z】。」
  • 「我们尝试过【方案】但未成功,原因是【机制解释】。」

三、逻辑关系:四个交接契约

这四条是全文逻辑关系的骨架。每一条断裂,都会让后面所有内容失效。

交接点 上游必须交出 下游才能成立 常见断裂
A ①→② 可归因的瓶颈:现象 + 量化 + 定位 + 机制 命题有真实的靶子 讲的是显存,解的是算力——靶子错位
B ②→③ 有约束、有判据、有边界的命题 方法的取舍有依据 没有约束 → 方法看起来是「随便选的」
C ③→④ 可独立验证的机制 + 已声明的取舍 实验能逐条对应判据 报了一堆数,但和②的判据对不上
D ④→① 同一指标下的闭环数据 论证闭合 换了指标,读者读不出「瓶颈被解决了」

顺序为什么不能换:

  • 先说瓶颈,才能定义问题——否则问题无的放矢;
  • 先定义问题,才能评价方法——否则没有判据;
  • 先有方法,才能设计实验——否则不知道测什么;
  • 结果必须回到瓶颈——否则论证不闭合,只是一份性能报告。

一种很常见的伪结构:以「我们做了一个 X」开头。它把方法放在第一位,导致读者在前半篇里无法评价任何东西——不知道这个 X 是为什么存在的、好在哪、和谁比。方法不应该是起点,它应该是结论。


四、两处必备补丁

补丁 1 · Gap:现有方案为什么不够

位置:②和③之间(或作为②的后半段)。

内容要求:把现有方案分成几类,每类为什么不够。关键约束:每一条「不够」都必须对应②里的一个约束。

作用:把③变成唯一剩下的选择。没有 Gap,方法就是「众多可能中的一种」;有了 Gap,方法就是「排除法之后的那一个」。

失败模式:把 Related Work 写成清单式罗列——「A 做了……B 做了……C 做了……」,没有逐条否定,读者读完不知道你为什么要另起炉灶。

正确写法:

现有方案分三类。① 近似类(稀疏化、低秩)精度不可控,违反约束 A;② 系统类(更快的 kernel)不改变访问量,触及约束 B 的上界;③ 硬件类(更大显存)在目标场景不可得。因此剩下的唯一方向是:在精确前提下降低访问量。

补丁 2 · 代价与边界

位置:挂在④上(论文里通常单列 Limitations 一节)。

「最终解决了什么问题」这句话最容易写成单边宣传。完整表述必须是三段式:

解决了 X(给出证据)→ 但代价是 Y(给出数据)→ 所以适用区间是 Z(给出条件与降级策略)。

缺了后两句,结果部分就从「科学结论」退化成「营销文案」。

为什么这一条尤其重要:它是唯一能证明「你真的做过实验」的证据。一个只有收益没有代价的结果,读者默认会怀疑两件事——要么你没测全,要么你在挑数据。


五、论文 vs 技术方案:差异与增补

共同骨架:四段式 + Gap + 代价边界。这部分完全一致。

论文额外需要

部分 要点
Related Work 的定位 不是罗列,是「我们和他们的关系」:谁解决了哪部分、谁和我们在哪个维度正交
消融实验 每个设计选择的独立贡献
复现性细节 超参、硬件、随机种子、原始数据
强基线 SOTA,而不只是「我们改之前」
Limitations / Future Work 独立成节,不与 Discussion 混在一起

技术方案(proposal)额外需要

部分 要点 为什么
可行性论证 为什么现在做得到:已有基础设施、前人验证、原型数据 方案没有结果,必须用「可行性」替代「已实现」
风险与对策 最大的 3 个风险 + 触发条件 + 退路 决策者最关心的是「失败了怎么办」
里程碑与验收标准 分阶段交付物 + 每阶段的通过条件 让方案可以被中途叫停,降低决策成本
资源估算 人力、算力、时间 没有成本的方案不是方案
不做清单 明确砍掉什么 保护 scope,防止无限膨胀
结果部分改写 从「结果」改为「预期结果 + 验证方式」 你还没有结果,写预期才诚实

一个判断技巧:如果一份 proposal 里找不到「不做清单」和「退路」,它大概率会被打回——因为决策者读到的是一份愿望,而不是一个可执行的计划。


六、章节骨架

论文

Title
Abstract                      ← 四段式各一句(含代价)

1  Introduction
  1.1 现象与量化               ← ①
  1.2 问题与约束、非目标        ← ②
  1.3 现有方案为何不够          ← Gap
  1.4 贡献列表(3 条,每条可证伪)
2  Background / Problem Formulation
                               ← ② 的正式化:符号、目标函数、约束
3  Related Work                ← 逐类否定,不是罗列
4  Method
  4.1 核心洞察(一句话)
  4.2 组件设计与约束的映射
  4.3 取舍与为什么不是更简单的做法
5  Evaluation
  5.1 实验设置(可复现性)
  5.2 与判据的逐条对应
  5.3 闭环到瓶颈(同一指标)
  5.4 基线与消融
  5.5 代价与适用区间
  5.6 失败实验
6  Limitations & Discussion
7  Conclusion

技术方案

0  一页纸摘要                  ← 四段式各一句 + 预期收益 + 主要风险
1  背景与瓶颈                  ← ①
2  目标与非目标                ← ② + out of scope
3  现有方案评估                ← Gap,逐类否定
4  技术方案
   4.1 架构总览
   4.2 关键机制(每个机制对应一条约束)
   4.3 取舍
5  预期结果与验证方式          ← ④ 的 proposal 版
6  可行性论证
7  风险与对策
8  里程碑与验收标准
9  资源估算
附录  接口 / 数据结构 / 伪代码

可直接复制的填空版见 paper_skeleton_zh.md。


七、用同一个四段式填三个真实工作

同一套框架,套三个不同性质的工作——你能看出它的通用性。

例 1 · FlashAttention(公开论文,定性)

段 内容
① 瓶颈 标准 attention 要把 N×N 的分数矩阵写进 HBM 再读回来。长序列下显存占用 O(N²),且 attention 从 compute-bound 退化为 memory-bound
② 问题 在不引入任何近似的前提下,能否降低 attention 的 HBM 访问量,并让显存随序列线性增长?约束:结果必须与标准 attention 完全一致
Gap 稀疏化 / 低秩近似类方案牺牲精度(违反约束);更快的 kernel 不改变访问总量(触及上界)
③ 方法 洞察:softmax 的归一化不必等整行算完——可以分块在线完成。因此永远不需要同时看到整行分数。→ 把 Q/K/V 分块载入 SRAM,块内算局部 softmax,用 running max / running sum 重标定累加
④ 结果 精确(非近似)attention;显存 O(N);长序列下注意力显著加速。代价:需要手写 fused kernel,实现复杂度高;短序列与算力已饱和的场景收益有限

例 2 · PagedAttention / vLLM(公开论文,定性)

段 内容
① 瓶颈 KV cache 按「最大可能长度」预分配连续显存,内部碎片 + 外部碎片导致显存利用率只有 20–40%。这直接限制了并发 batch size,进而限制吞吐
② 问题 能否在不改变 attention 数学(结果完全一致)的前提下,让 KV cache 按需分配、几乎无浪费,且不牺牲吞吐?
Gap 现有系统要么继续按最大长度预留(浪费),要么重算(更慢)。没有一类方案同时满足「零浪费」和「不重算」
③ 方法 洞察:KV cache 和操作系统的虚拟内存是同构的——都可以用「逻辑块 → 物理块」的间接映射消除碎片。→ 序列切成固定大小 block,block table 做映射,attention kernel 按 block 做 gather
④ 结果 显存浪费从 60–80% 降到 <4%,吞吐相对当时 SOTA 提升数倍。代价:非连续访存 + block table 间接寻址使 kernel 更复杂;block 粒度带来固有开销(例如最后一个块无法复用)

例 3 · INT8 KV Cache(你自己的 nano-vLLM 工作,带实测数字)

用你 interview_qa_zh.md 里已经核实过的数据填一遍——这是三者中最完整的一个,因为它真的写出了代价:

段 内容
① 瓶颈 KV cache 按剩余显存定容。RTX 3060 Laptop 6 GiB 上只能容纳 92 个 block,上下文容量与并发被显存卡死。量化后每 token 的 KV 从 256 B 降到 130 B
② 问题 能否把每 token KV 字节数降到约 1/2,从而提升上下文容量,且 attention 数值误差可控?约束:不改变 attention 输出的数值量级;scale 不能破坏 prefix cache 的哈希与引用计数逻辑
Gap per-tensor 量化精度差(违反数值约束);粗化到整个 block 共用 scale 对长尾分布不友好;物化浮点副本会把省下的带宽还回去
③ 方法 洞察:KV 的精度需求远低于权重,per-token / per-KV-head 对称量化 + 融合反量化就够。→ 写入时在 store kernel 内量化(/127 免 clamp、round-half-away-from-zero);decode 在 Paged Attention kernel 内融合反量化;scale 与 data 共用 physical block ID,不改变哈希
④ 结果 每 token 字节 256 → 130(50.78%),可用 block 92 → 179(1.95×);attention 输出 cosine 0.999958。代价:prefill 侧反量化需要物化浮点张量,端到端反而 +18.3% 慢(prefill −25.3%)。因此定位为「用吞吐换上下文容量」的可选模式,不设为默认。边界:未做 perplexity / 下游质量评估,64-token exact agreement 仅 46.875%,不足以宣称语言质量无损

例 3 值得反复看的两个地方: ① 「涨的是块数,不是省了显存」——KV cache 按剩余显存定容,所以 kv_storage_bytes 几乎没变。这个表述的准确性,就是①里「量化」这一步做到位的体现。 ② 「exact token agreement 不是语言质量指标」——这是④里最容易犯的指标错配。你没有拿它去冒充质量无损,而是明确划成边界。这一步让整篇结论的可信度上了一个台阶。


八、审稿人视角:五个致命问句

写完初稿后,把自己当审稿人,逐条回答。答不上来的地方就是论证断裂点。

# 问句 攻击的是哪一段
1 这个瓶颈是真的吗?换个场景还成立吗? ① 归因是否机制级
2 为什么不用更简单的办法? ③ 有没有 Gap
3 你的基线是不是挑软的捏? ④ 基线选择
4 你的指标和你的目标是一回事吗? ②↔④ 判据是否对齐
5 代价是什么?什么情况下会失效? 补丁 2 是否缺失

自查清单:

  • [ ] 瓶颈有数字、有 profiler 证据、有机制解释
  • [ ] 问题有目标、有约束、有非目标、有阈值判据
  • [ ] Gap 逐类否定,且每条「不够」都对应一条约束
  • [ ] 方法的核心洞察能用一句话说完
  • [ ] 每个组件都能指回①②里的某一条
  • [ ] 取舍写清楚了,并解释了为什么可接受
  • [ ] 结果逐条对应②的判据,没有换指标
  • [ ] 用①的同一指标做了闭环
  • [ ] 基线是 SOTA,不只有「我们改之前」
  • [ ] 有消融、有失败实验
  • [ ] 代价、适用区间、降级策略都写了
  • [ ] 硬件 / 模型 / shape / 模式 / 原始数据可复现

九、写作顺序建议:不要从摘要开始写

不要按 ①→②→③→④ 的顺序写。 那样写,①很容易变成「我想做的方向」,而不是「我证明了的东西」。

建议的写作顺序:

第 1 步  写 ④ 的数据表
        理由:数据是你唯一不能编的东西,先把它固定下来
第 2 步  写 ③ 的核心洞察句(一句话)
        理由:如果这句话写不出来,说明你还没想清楚,别往下写
第 3 步  写 ② 的判据
        理由:判据必须和第 1 步的数据表逐条对齐
第 4 步  写 ① 的归因
        理由:归因必须指向第 2 步的洞察——这是 A→B→C 的逆向检查
第 5 步  写 Gap
        理由:此时你才知道需要排除掉哪些替代方案
第 6 步  最后写 Abstract
        理由:四段式各一句,此时才可能写顺

理由一句话总结:①②是从结果倒推出来的,不是从兴趣正推出来的。 先有数据和洞察,再回头构造动机和问题,论证链才是闭合的;反过来写,很容易出现「动机很大、结果很小」的错位——这正是审稿人最常攻击的点。


十、一页速查

段 唯一任务 必须交出 最常见失败
① 瓶颈 把「慢」变成可归因的原因 现象 + 量化 + 定位 + 机制 只有形容词;只有相关性没有机制
② 问题 把「要加速」变成可证伪的命题 目标 + 约束 + 非目标 + 判据 目标不可度量;没有约束
Gap 把方法变成排除法之后的那一个 逐类否定,每条对应一条约束 写成 Related Work 清单
③ 方法 让方案看起来是约束的必然推论 一句话洞察 + 组件映射 + 取舍 上来就讲实现;回避取舍
④ 结果 用②的判据证明命题,并交代代价 判据对应 + 闭环 + 区间 + 失败实验 换指标;挑数据;不写代价

三句话记住全部:

  1. 四段是一条链,不是四个格子——每段都要把接力棒交出去。
  2. 补上 Gap 和代价边界——缺前者方法凭空出现,缺后者结论变成宣传。
  3. 从结果倒着写——先固定数据,再构造动机。
Infra Notes · 从原理走向实现基于 Markdown 构建