<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>The Herta</title><link>https://letsgetai.github.io/</link><description>Recent content on The Herta</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 31 Aug 2026 00:30:00 +0800</lastBuildDate><atom:link href="https://letsgetai.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>OPD 本质分析：从在线蒸馏公式、TRL 最小复现到 GSM8K 验证</title><link>https://letsgetai.github.io/posts/opd-on-policy-distillation-trl-repro/</link><pubDate>Mon, 31 Aug 2026 00:30:00 +0800</pubDate><guid>https://letsgetai.github.io/posts/opd-on-policy-distillation-trl-repro/</guid><description>&lt;blockquote&gt;
&lt;p&gt;一句话版本：OPD（on-policy distillation，在线策略蒸馏）用「学生自己采样的数据」加「教师逐 token 的密集信号」，同时绕开离线蒸馏的分布错位和纯 RL 的信号稀疏。我们基于 TRL 做了一次最小复现，得到三个可量化的结论：数据筛选把 GSM8K 准确率从 11.52% 抬到 43.06%；换更强的教师做离线蒸馏几乎不动（43.06% → 43.21%）；只有「强教师 + 完整生成预算」的组合下，on-policy 的价值才兑现（54% &amp;gt; 42% &amp;gt; 39%）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文面向已经接触过 RL 和蒸馏、想理解 OPD 来龙去脉并动手复现的读者。主线：OPD 本质是什么 → TRL 怎么实现 → 我们的实验证明了什么 → 结论能否被外部证据验证。&lt;/p&gt;
&lt;h2 id="开篇opd-的本质"&gt;开篇：OPD 的本质&lt;/h2&gt;
&lt;h3 id="为什么现在都在谈-opd"&gt;为什么现在都在谈 OPD&lt;/h3&gt;
&lt;p&gt;OPD 最近在大模型后训练里升温：Qwen3、GLM-5、DeepSeek 的后训练实践都涉及「在线蒸馏」思路，社区里也有不错的入门视频：&lt;a href="https://www.bilibili.com/video/BV1bNGz6xEQf/"&gt;从 RL 到 OPD：Qwen3、GLM-5、DeepSeek 都在关注什么？&lt;/a&gt;。核心主张一句话：保留 RL 里「学生自己探索」的 on-policy 采样，同时引入教师对每个 token 的密集反馈，缓解传统蒸馏的分布错位，也降低纯 RL 里信号稀疏、成本高、训练不稳定的压力。&lt;/p&gt;
&lt;h3 id="三范式对比"&gt;三范式对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;离线蒸馏 offline KD&lt;/th&gt;
&lt;th&gt;OPD 在线策略蒸馏&lt;/th&gt;
&lt;th&gt;RL（PPO/GRPO）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;采样分布&lt;/td&gt;
&lt;td&gt;教师或固定数据（off-policy）&lt;/td&gt;
&lt;td&gt;学生当前策略（on-policy）&lt;/td&gt;
&lt;td&gt;学生当前策略（on-policy）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;学习信号&lt;/td&gt;
&lt;td&gt;教师逐 token 分布&lt;/td&gt;
&lt;td&gt;教师逐 token 分布&lt;/td&gt;
&lt;td&gt;奖励（通常稀疏）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;是否要奖励模型&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分布错位&lt;/td&gt;
&lt;td&gt;有&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;信号密度&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;不稳定风险&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中（依赖采样质量）&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;本质是两个维度的交集：「谁的数据」决定分布是否错位——离线蒸馏用教师生成的数据，学生学的是「自己不太会产生的输入」上的分布，且固定数据不会随学生进步自适应；「谁的信号」决定密度——教师逐 token 的 KL 目标密集，RL 的奖励通常只出现在序列末尾。OPD 取交集：学生数据 × 教师信号。&lt;/p&gt;</description></item><item><title>AI 写代码不膨胀：把治理放在事后，而不是写进 prompt</title><link>https://letsgetai.github.io/posts/ai-code-governance/</link><pubDate>Fri, 28 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/ai-code-governance/</guid><description>&lt;h2 id="场景10-周13147-条-commit"&gt;场景：10 周，13,147 条 commit&lt;/h2&gt;
&lt;p&gt;AI 辅助开发把代码的累积速度提高了一个量级，随之而来的问题是项目越写越“堆”：功能在快速扩张，结构在失去秩序。最直觉的应对是在 prompt 里加约束——“做最小实现”“不要过度抽象”。本文的结论是：这类事前限制控制不了膨胀，起作用的是事后治理——用固定门禁拦住可机械检测的结构问题（坏味道，如重复代码与死代码），用定期重构和去重抽象控制长期累积。核心证据来自 &lt;a href="https://github.com/deepseek-ai/deepseek-harness"&gt;deepseek-harness&lt;/a&gt; 的公开 commit 史。&lt;/p&gt;
&lt;p&gt;deepseek-harness（下文简称 DSH）是 DeepSeek 在 GitHub 上公开的仓库，在 2026-06-10 至 2026-08-21 的 10 周里积累了 13,147 条 commit，峰值一天 889 条。commit 主题与分支名中留有大量 AI 编码代理参与的痕迹（codex/ 分支前缀、.agents/ 目录）。这些数字全部来自公开数据，附录给出了可复现的统计命令，读者可以自行验证。&lt;/p&gt;
&lt;p&gt;&lt;img alt="每周 commit 数" loading="lazy" src="https://letsgetai.github.io/images/ai-code-governance/weekly-commits.png"&gt;&lt;/p&gt;
&lt;h2 id="commit-史数据三个反直觉的分布"&gt;commit 史数据：三个反直觉的分布&lt;/h2&gt;
&lt;p&gt;提交类型按 commit 主题首词归类统计（命令见附录）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;数量&lt;/th&gt;
&lt;th&gt;占比&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;5,891&lt;/td&gt;
&lt;td&gt;45%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fix&lt;/td&gt;
&lt;td&gt;2,490&lt;/td&gt;
&lt;td&gt;19%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;docs&lt;/td&gt;
&lt;td&gt;1,435&lt;/td&gt;
&lt;td&gt;11%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;test&lt;/td&gt;
&lt;td&gt;1,028&lt;/td&gt;
&lt;td&gt;8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;feat&lt;/td&gt;
&lt;td&gt;745&lt;/td&gt;
&lt;td&gt;6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;refactor&lt;/td&gt;
&lt;td&gt;494&lt;/td&gt;
&lt;td&gt;4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;revert&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;0.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;其他&lt;/td&gt;
&lt;td&gt;1,028&lt;/td&gt;
&lt;td&gt;8%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img alt="提交类型分布" loading="lazy" src="https://letsgetai.github.io/images/ai-code-governance/commit-types.png"&gt;&lt;/p&gt;
&lt;p&gt;三个反直觉的发现：&lt;/p&gt;</description></item><item><title>Codex Goal 模式：什么时候用、怎么用</title><link>https://letsgetai.github.io/posts/codex-goal-mode/</link><pubDate>Wed, 26 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/codex-goal-mode/</guid><description>&lt;h2 id="一个把-p95-压到-200ms-的任务"&gt;一个把 p95 压到 200ms 的任务&lt;/h2&gt;
&lt;p&gt;假设你让 agent 把服务的 p95 延迟压到 200 毫秒以下（p95 指 95% 的请求延迟低于这个值，是性能优化常用的目标——意思是只允许最慢的 5% 请求超过它）。这件事没法一条命令做完：要先跑 profile 定位热点，改实现，再跑基准对比，确认没有回退；没达标就换一个方向重来。十几轮工具调用，每一轮都改一点东西。开头 agent 清楚方向，二十轮之后它可能已经忘了最初的目标，或者在一个局部优化里越钻越深，或者自己宣布「完成了」——但基准根本没达标。&lt;/p&gt;
&lt;p&gt;这类任务有个名字：长程任务（long-horizon task），指需要很多轮连续动作、最后还要验证结果才算完成的任务。你的问题很具体：这类任务里 agent 为什么容易跑偏、停不下来？Codex 的 goal 模式能不能解决？什么时候用、怎么写？&lt;/p&gt;
&lt;p&gt;暂定回答：goal 模式解决的是「完成判定与续跑机制」的缺失，而不是模型能力本身。它适合有明确终点但路径不确定的任务；使用时要把目标写成可验证的证据面，并配合 token 预算；官方推荐的完整流程是先 /plan 访谈澄清，再 /goal 建立目标。&lt;/p&gt;
&lt;h2 id="长程任务为什么难断崖不在单步在串起来"&gt;长程任务为什么难：断崖不在单步，在「串起来」&lt;/h2&gt;
&lt;p&gt;先排除一个常见误解：单步能力已经不是瓶颈。OpenAI 官方跑过 25 小时、1300 万 token 的连续任务实验，模型可以长时间稳定工作；METR 的度量进一步指出，「50% 可靠完成」的任务时长大约每 7 个月翻一番，2025 年初已经到了小时级——瓶颈是把长动作序列串起来，而不是单步技能。&lt;/p&gt;
&lt;p&gt;benchmark 把这种断崖画得更直白。在 SWE-bench Verified（500 个单 issue 任务）上 gpt-5.2 能做到约 72.8%；换成 SWE-EVO（48 个 release 级任务，平均涉及 21 个文件），同样的模型掉到 22.9%；SWE-bench Pro（1865 个企业级长任务）上 Top 模型约 23%；LongCLI-Bench 的 20 个长程 CLI 任务，SOTA 不到 20%，多数 agent 卡在 30% 进度之前。&lt;/p&gt;</description></item><item><title>主流大模型为什么都是 MoE：从 DeepSeek-V3 到 Qwen3.8 的架构演进</title><link>https://letsgetai.github.io/posts/moe-architecture-2026/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/moe-architecture-2026/</guid><description>&lt;blockquote&gt;
&lt;p&gt;结论先行：2026 年的主流开源模型（DeepSeek-V3/V4、Qwen3.8）不约而同选择了 MoE——把 FFN 拆成数百个专家、每个 token 只激活其中几个。这不是跟风，而是三个结构性问题同时被 MoE 解决的必然结果：容量与算力解耦、注意力与解码的双重优化、加速机制内建于训练。这篇文章从 DeepSeek-V3 的细节讲起，把 MoE 的每个零件、注意力的两条改进路线、MTP 的来龙去脉，以及“小模型为什么不用 MoE”，按我自己的逻辑线一次讲清楚。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="引子一个值得注意的现象"&gt;引子：一个值得注意的现象&lt;/h2&gt;
&lt;p&gt;2024 年之前，主流大模型是两种形态：dense 的（GPT-3、Llama）和稀疏的（GShard 式的 MoE）。到 2026 年，事情变了：DeepSeek 全线 MoE（V3 的 671B、V4 的 284B/1.6T），Qwen 的主力也变成 MoE（Qwen3.8-2.4T-A95B），连“80B 总参、3B 激活”的中间档（Qwen3-Next）都是 MoE。dense 只留在小模型区（Qwen 的 0.6B-32B）。&lt;/p&gt;
&lt;p&gt;为什么？答案是 MoE 同时解决了两类问题：训练侧，它把“模型容量”和“每 token 算力”解耦，让你可以养一个 600B 的模型而每次推理只花 37B 的钱；推理侧，它和注意力压缩、MTP（多 token 预测）叠加，把单步成本和步数同时压下来。下面从零件讲起。&lt;/p&gt;
&lt;h2 id="一moe-是什么把-transformer-的-ffn-拆开"&gt;一、MoE 是什么：把 Transformer 的 FFN 拆开&lt;/h2&gt;
&lt;p&gt;以 DeepSeek-V3（2024 年 12 月）为例——它是第一个把 MoE 细节大规模定型的模型，也是理解后续一切的地基：671B 总参数、37B 每 token 激活。&lt;/p&gt;
&lt;h3 id="11-专家的结构与数量"&gt;1.1 专家的结构与数量&lt;/h3&gt;
&lt;p&gt;Transformer 的 FFN 层被替换成 MoE：1 个&lt;strong&gt;共享专家&lt;/strong&gt; + 256 个&lt;strong&gt;路由专家&lt;/strong&gt;，每个 token 激活 Top-8 个路由专家，专家中间维 2048。共享专家永远参与，负责通用能力；路由专家做细粒度分工。&lt;/p&gt;</description></item><item><title>AI 写文档为什么会写偏和被污染：根因与三层解法</title><link>https://letsgetai.github.io/posts/ai-writing-context-isolation/</link><pubDate>Mon, 24 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/ai-writing-context-isolation/</guid><description>&lt;blockquote&gt;
&lt;p&gt;你说的对，番茄炒蛋的计划已经约束了任务范围，但是执行完全失控了。我把大量精力放在做东坡肉上，却没有保住番茄炒蛋不需要加酱油的任务边界。实际发生的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;番茄炒蛋里加了东坡肉；&lt;/li&gt;
&lt;li&gt;番茄炒蛋里加了酱油。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当前所有的烹饪进程都已停止。下一步不应该继续往蛋炒饭里加东坡肉和酱油，而是应该只做恢复：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;完整保留已经做好的番茄炒蛋基线；&lt;/li&gt;
&lt;li&gt;从当前的番茄炒蛋里去掉东坡肉和酱油；&lt;/li&gt;
&lt;li&gt;实际验收：番茄炒蛋里没有任何的东坡肉和酱油；&lt;/li&gt;
&lt;li&gt;更新菜谱，写入菜谱边界：番茄炒蛋里不应该存在东坡肉和酱油。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由于当前的番茄炒蛋里没有 git 历史，我不会擅自覆盖现有的番茄炒蛋，下一步我只做番茄炒蛋的恢复并证明吃起来确实是番茄炒蛋，不再做任何的调料添加。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这段回复浓缩了两类问题。一是交付偏离意图：要番茄炒蛋，得到的是加了东坡肉和酱油的番茄炒蛋。二是被否决内容持续在场：整段回复都在处理早已被否掉的东坡肉和酱油，末尾还附上防御性自我声明——&amp;ldquo;不会擅自覆盖&amp;quot;&amp;ldquo;不再添加&amp;rdquo;，像在为一场没人要求的辩护做准备。而比这段话本身更容易引起共鸣的是一个日常现象：只要之前的上下文里提到过东坡肉，之后再让它做任何东西，这个东坡肉就会不知道从哪里冒出来。换任务也甩不掉它，因为它不在任务里，在上下文里。&lt;/p&gt;
&lt;p&gt;本文的回答是：写偏和污染的共同根因，都是在带噪声的上下文里直接生成。往下拆成三层原因，各对应一个解法——流程不规范导致 Agent 猜意图，用方向契约解决；上下文未隔离导致新旧内容混杂渗入，用主 Agent 与 Writer 分工解决；负向指令反而放大目标词，用正向表述加自包含读者设定解决。&lt;/p&gt;
&lt;h2 id="两类问题落到文档场景是什么样"&gt;两类问题落到文档场景是什么样&lt;/h2&gt;
&lt;p&gt;写偏容易识别：你要一篇面向工程师的技术分享，拿到的可能是面向管理层的汇报，或者结构对、重点全漂。难察觉的是污染，它有两个形态。形态一叫残留：你删掉了某个方案，下一稿的摘要里它又出现了，只是换了措辞。形态二叫串场：之前会话里提过的任何东西，都会在后续无关任务里冒头，就像那块东坡肉——它甚至能跨过&amp;quot;这是一个新任务&amp;quot;的边界。两个形态共享同一个来源：生成时模型看得见的所有内容，都是潜在的生成材料。&lt;/p&gt;
&lt;h2 id="论文证据多轮上下文里的系统性退化"&gt;论文证据：多轮上下文里的系统性退化&lt;/h2&gt;
&lt;p&gt;这两个现象不是个例。微软研究院的论文《LLMs Get Lost In Multi-Turn Conversation》（&lt;a href="https://arxiv.org/abs/2505.06120"&gt;arXiv:2505.06120&lt;/a&gt;，ICLR 2026 Outstanding Paper）把同一类问题系统量化了：他们把 6 类生成任务（代码、数据库、工具调用、Data-to-text、数学、摘要）的完整指令拆成多轮逐步揭示，让 15 个 LLM 在单轮和多轮两种设定下分别完成任务。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Figure 1：多轮对话中 15 个模型的表现退化，蓝点为单轮（Full），红点为多轮（Sharded）" loading="lazy" src="https://letsgetai.github.io/images/ai-writing-context-isolation/fig1-teaser.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;图 1 来自论文 Figure 1。多轮设定下 6 任务平均性能下降 39%，分解为 aptitude（最佳情况下的表现）下降约 16% 和 unreliability（最好与最差情况的差距）上升 112%。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;关键不只是&amp;quot;变差了&amp;rdquo;，而是&lt;strong&gt;差在哪里&lt;/strong&gt;。作者把性能损失拆成两个成分：aptitude（模型在最佳情况下的能力）只小幅下降，真正放大的是 unreliability——同一模型在最好和最坏会话之间的差距上升 112%。换句话说，能力还在，但发挥极不稳定。论文进一步发现一个和文档写作直接相关的机制：模型倾向于在信息不完整时就过早作答，一旦答错，这个错误答案会固化为后续决策的依赖，很难被后面揭示的信息纠正。Table 6 的数字更直白：在前 20% 轮次就首次作答的会话，平均性能 30.9；等到最后 20% 轮次才作答的，是 64.4——&lt;strong&gt;过早作答的会话性能不到延迟作答的一半&lt;/strong&gt;。这和我们写文档时&amp;quot;模型读完一半材料就开始输出结构、后面怎么改都扭不过来&amp;quot;的体验是同一个机制。&lt;/p&gt;
&lt;h2 id="原因一信息多指令少剩下的靠猜"&gt;原因一：信息多，指令少，剩下的靠猜&lt;/h2&gt;
&lt;p&gt;写文档的典型输入是一堆素材加一句模糊指令：&amp;ldquo;把这些资料整理成技术分享。&amp;ldquo;素材提供了内容，却没提供决定：写给谁、回答什么问题、多长、什么算证据。这些决定不会被跳过，只会被模型按最像的样本补全——猜的方向和你的意图不一致，就是写偏。这不是偶发事故，而是长期多轮写作对话里的普遍观察。Claude Code 的官方文档把这个取舍说得很直白：&lt;a href="https://code.claude.com/docs/en/best-practices#let-claude-interview-you"&gt;花时间把 spec（需求规格）写精确，比盯着实现过程更有回报&lt;/a&gt;。指令模糊的时候，精确的不是 spec，是模型的想象。&lt;/p&gt;</description></item><item><title>用 Agent 做 DSL 算子的结构级优化：现在能做到什么程度</title><link>https://letsgetai.github.io/posts/dsl-operator-agent-optimization/</link><pubDate>Fri, 21 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/dsl-operator-agent-optimization/</guid><description>Agent 已能对结构清晰、参考实现明确的算子稳定拿到 2-5x 加速；量化与复杂融合仍未解决。</description></item><item><title>注意力内核进化史：FlashAttention 系列与 Flash Linear Attention</title><link>https://letsgetai.github.io/posts/flash-attention-evolution/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/flash-attention-evolution/</guid><description>&lt;h2 id="一句话结论"&gt;一句话结论&lt;/h2&gt;
&lt;p&gt;FlashAttention 系列解决了&amp;quot;标准 attention 在 GPU 上跑不快&amp;quot;的系统问题——不改数学、不牺牲精度，靠 tiling（分块）和 IO-aware（感知内存层次）设计把 attention 推向硬件极限；Flash Linear Attention（FLA）系列则用同样的分块思想，把理论 O(N) 的线性 RNN 内核也提速到超越 FlashAttention。两条线在&amp;quot;长上下文高效序列建模&amp;quot;上汇合，共同构成了今天大模型长上下文能力的底层基础设施。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;先说清一个名字：&lt;strong&gt;FlashAttention&lt;/strong&gt; 是一系列论文（2022–2024），优化的是标准的 softmax attention；&lt;strong&gt;Flash Linear Attention（FLA）&lt;/strong&gt; 是一个开源项目（2024 起），优化的是线性 attention / 线性 RNN。两者共享&amp;quot;分块 + 避免 HBM 往返&amp;quot;的思想，但不是同一个东西。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="为什么-attention-慢gpu-内存层次是第一瓶颈"&gt;为什么 attention 慢：GPU 内存层次是第一瓶颈&lt;/h2&gt;
&lt;p&gt;标准 attention 需要计算 QK^T，时间与内存都随序列长度 N 二次增长。但很多人忽略一个更实际的问题：&lt;strong&gt;GPU 上跑的慢，往往不是算得慢，而是搬数据搬得慢&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;GPU 内存是分层的：HBM（高带宽内存，容量大但慢）和片上 SRAM（容量小但快）。朴素实现把 N×N 的注意力矩阵完整写进 HBM 再读回来，大量时间花在内存搬运上，而不是矩阵乘上。&lt;/p&gt;
&lt;p&gt;FlashAttention 系列盯住的就是这个&amp;quot;内存搬运&amp;quot;问题，用一句话概括它的核心策略：&lt;strong&gt;把中间结果留在离计算单元最近的地方，绝不落盘到 HBM&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;先给出标准 attention 的数学形式，后面所有优化都是围绕它展开的：&lt;/p&gt;
$$
\text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V, \quad S = QK^\top \in \mathbb{R}^{N \times N}
$$&lt;p&gt;其中 $Q, K, V$ 是查询、键、值矩阵，$N$ 是序列长度，$d$ 是每个头的维度。问题在于中间矩阵 $S$ 是 $N \times N$，序列变长时它主导了内存和时间。&lt;/p&gt;</description></item><item><title>约束解码的生成：从逐 token 采样，到“知道下一步是什么”</title><link>https://letsgetai.github.io/posts/constrained-decoding/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/posts/constrained-decoding/</guid><description>&lt;blockquote&gt;
&lt;p&gt;生成一段 JSON 时，模型其实有 95% 的时间都在做“确定的重复”：&lt;code&gt;{&lt;/code&gt;、&lt;code&gt;&amp;quot;&lt;/code&gt;、字段名、&lt;code&gt;:&lt;/code&gt;、&lt;code&gt;}&lt;/code&gt;。真正需要模型“想”的，可能只有每个字段的值。那能不能告诉解码器：这些位置不用采样，直接填？如果再把“猜下一步”交给一个更快的草稿模型，生成会不会快好几倍？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文是围绕这个问题的技术分享，面向已经接触过 LLM 推理、想理解约束解码来龙去脉的读者。主线是：约束解码解决什么问题 → 方法如何一步步演进 → 关键证据支持哪些结论 → 实践中的经验与边界。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心猜想&lt;/strong&gt;：约束解码里大量内容是确定性重复（固定字段、括号、键名），能否把“确定的部分直接跳过采样、交给更快的前向”做成加速？这条主线贯穿全文，也是约束解码与投机解码（speculative decoding）能走到一起的原因。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="问题与背景"&gt;问题与背景&lt;/h2&gt;
&lt;p&gt;约束解码要解决的核心问题：&lt;strong&gt;输出必须满足结构约束&lt;/strong&gt;（正则、JSON Schema、CFG），且正确性要有保证，而不是“运气好碰对格式”。&lt;/p&gt;
&lt;p&gt;约束解码与普通解码的差别在于，每一步都要回答“哪些 token 合法”。这个查询与 mask 本身有成本，于是出现两条演进方向：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;约束怎么表达&lt;/strong&gt;：从“必须包含指定词”（集合级约束），到“必须匹配某种语法”（FSM 可判定的约束）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;约束怎么不花钱&lt;/strong&gt;：从逐 token 串行查表，到预计算、跳确定部分、与 GPU 前向重叠、最后与投机解码并行验证。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下文按“问题 → 方法 → 证据”展开，论文链接直接列在对应方法处。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一早期约束解码约束做进搜索过程"&gt;一、早期约束解码：约束做进搜索过程&lt;/h2&gt;
&lt;p&gt;约束解码最早解决的问题是“输出必须包含某些指定内容”——不是格式合法，而是句子里必须出现某个词或短语。早期方法把约束做进 beam search 的搜索过程。&lt;/p&gt;
&lt;h3 id="grid-beam-searchhokamp--liu-acl-2017"&gt;Grid Beam Search（Hokamp &amp;amp; Liu, ACL 2017）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;论文：&lt;em&gt;Lexically Constrained Decoding for Sequence Generation Using Grid Beam Search&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;链接：&lt;a href="https://aclanthology.org/P17-1141/"&gt;https://aclanthology.org/P17-1141/&lt;/a&gt; 、 arXiv:1704.07138&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;方法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;约束定义为“输出必须包含一组指定的短语/词”。&lt;/li&gt;
&lt;li&gt;模型在 beam 上扩展时，额外维护一个“已覆盖约束”的状态，beam 排序优先覆盖更多约束的候选。&lt;/li&gt;
&lt;li&gt;约束是集合级的“必须包含”，不要求前缀匹配，可以出现在输出任意位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;判断&lt;/strong&gt;：这一代方法把约束做进搜索，正确，但只覆盖“必须包含词”这一种约束，且 beam 扩展成本随约束数量上升。它的意义是确立了“约束进解码过程”的范式，而不是进训练或后处理。&lt;/p&gt;</description></item><item><title>About</title><link>https://letsgetai.github.io/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://letsgetai.github.io/about/</guid><description>&lt;p&gt;&lt;a href="https://github.com/letsgetai"&gt;GitHub&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>