读见

防止模型崩溃所需的新鲜数据是修复它的 13-28 倍

原题Preventing model collapse costs 13-28x more fresh data than curing it

约 8 分钟约 1,893 字原文英文已翻译

读前速览

5 个要点

对一篇关于自消耗训练循环的论文的复现表明,被广泛引用的 1–30% 新鲜数据范围混淆了三个不同的问题,而防止崩溃所需的新鲜数据是修复崩溃的 13.4–27.6 倍。

  1. 民间闭式解 (1−p*)ⁿ 回答的问题与循环面临的问题不同。

    它是通过 Jensen 不等式得到的无条件损失概率下界,而循环经历的是当前符号消失的条件概率。实测比率中位数比该下界高 11.9 倍,而读数高于还是低于下界取决于符号缺失的频率——因此它在两个方向上都会出错,并非保守下界。

  2. 池窗口 w,而非新鲜数据比例,才是主导控制变量。

    在固定每代新鲜数据率的情况下,随着 w 从 1(替换)增长到 64(累积),稳定性边界下降两到三个数量级。移动平均松弛模型预测的实测比率误差在 2.62% 以内,而与之竞争的替换定律误差高达 32.8 倍。

  3. 与常识直觉相反,预防的代价远高于恢复。

    在相同的运行中,保持最差符号的稳态缺失率 ≤1% 所需的新鲜数据率,是拯救一个完全崩溃的循环所需数据率的 13.4–27.6 倍。「每一代每个符号都出现」比「每个符号最终都会回来」是更强的要求。

  4. 不存在严格的不可逆点,只有由 λ 和 w 设定的有限时间范围。

    对于所有 λ>0,循环都是遍历的,因此每个状态都与其他状态相通。192–435 倍的首次通过比率反映了有限时间范围内的滞后效应,而严重的删失(高达 0.965)意味着真实比率比打印出来的更大;一个单元格的恢复时间未定义,而不仅仅是很大。

  5. 任何新鲜数据比例都必须明确标准、协议和统计量。

    这三种选择分别相差 13.4–27.6 倍、高达 0.00101 倍和中位数 0.08437。缺少这三者的数字是未充分指定的,这——而非草率——解释了该领域 1–30% 的分布范围。

完整摘要

作者复现了一篇论文,该论文认为,已发表的关于自消耗训练循环的 1–30% 新鲜数据范围并非分歧,而是三个不同问题的混淆。第一,民间闭式解 (1−p*)ⁿ 是无条件损失概率的下界,而非循环所经历的条件概率;实测比率中位数比该下界高 11.9 倍,且方向取决于符号缺失比例。第二,控制变量是池窗口 w:在固定新鲜数据率的情况下,累积式流水线(w>1)比替换式流水线(w=1)接近崩溃的程度高两到三个数量级,移动平均松弛模型预测的误差在 2.62% 以内。第三,「稳定」分为预防(λ_stationary)和恢复(λ_heal),两者相差 13.4–27.6 倍,预防是代价高昂的标准——这与常识直觉相反。第四,对于所有 λ>0,循环都是遍历的,因此不存在严格的不可逆点,只有有限的时间范围;首次通过比率达到 192–435 倍,并伴有严重的删失。该论文预注册了三个信念,驳斥了其中两个(其中一个符号相反),并附带了一个包含 14 个植入损坏的 45 项检查验证套件。局限:这是一个在 K=8 个符号上的多项重采样循环,而非神经网络;可迁移的是结构,而非常数。

目录 · 8 节
查看原文

如果你用自己的输出进行训练,可能读到过一个关于“需要多少新数据”的数字。公开发表的范围大约是 1% 到 30%。人们通常把这种差异解读为意见不一——其中一个数字肯定是错的。If you train on your own output, you have probably read a number for "how much fresh data you need". The published range is roughly 1 % to 30 %. That spread is usually read as disagreement — one of those numbers must be wrong.

我花了一周时间复现一篇论文,它提出了一个不同的观点:离散度并不代表意见分歧,而是三个问题披着同一件外衣;人人引用的那个数字,甚至都不是它声称代表的那个量。I spent a week reproducing a paper that argues something different: the spread is not disagreement, it is three questions wearing one coat, and the number everyone quotes is not even the quantity it claims to be.

现在,在相信任何新鲜数据占比之前,我都会先检查以下四项,每项都有相应的测量依据。Here are the four things I now check before I believe any fresh-data fraction, each with the measurement behind it.

1. 作为速率引用的常数,是另一个量的下界。 1. The constant quoted as a rate is a lower bound on a different quantity

常用的闭式公式是 (1 − p*)ⁿ:在 n 次抽取中,漏掉一个真实频率为 p* 的符号的概率。它常被称为“每代损失”。The folk closed form is (1 − p*)ⁿ: the probability a symbol of true frequency p* is missed in n draws. It gets quoted as "the per-generation loss".

损失核为 ℓ_i(q) = (1 − λp* − (1−λ)q_i)ⁿ,它关于 q_i 是凸函数。循环过程的平稳均值恰好为 p*(递推关系 E[q_{t+1}] = p* + (1−λ)(E[q_t] − p*) 是精确的),因此由詹森不等式可得The loss kernel is ℓ_i(q) = (1 − λp* − (1−λ)q_i)ⁿ, which is convex in q_i. The loop's stationary mean is exactly p* (the recursion E[q_{t+1}] = p* + (1−λ)(E[q_t] − p*) is exact), so Jensen gives

E[ℓ_i(q)] ≥ ℓ_i(E[q]) = (1 − p*_i)ⁿ     for every i and every λ > 0
Enter fullscreen mode Exit fullscreen mode

因此,这种常见的经验形式给出的是无条件丢失概率的下界。但循环实际经历的是条件速率——即当前存在的符号消失的概率——这是对另一组状态取的另一种平均。So the folk form is a lower bound on the unconditional loss probability. But what a loop actually experiences is the conditional rate — the chance that a symbol now present disappears — and that is a different average, over a different set of states.

与直接模拟相比,在通过充分性门槛的 602 个逐符号读数中(密度 × 速率 ≥ 30,因此每个读数至少基于 30 次预期损失事件):Measured against direct simulation, over 602 per-symbol readings that pass an adequacy gate (density × rate ≥ 30, so each rests on at least 30 expected loss events):

count
measured rate above the bound 519 of 602
measured rate below the bound 83 of 602

界限与实测值之比的中位数为 0.08437——实测速率的中位数是界限的 11.9 倍。最小值为 2.83e-47。而在 83 个案例中,情况相反,差距最大为 6.03 倍。Median bound-to-measured ratio 0.08437 — the measured rate is a median 11.9× above the bound. Minimum 2.83e-47. And in the 83 cases it goes the other way, by up to 6.03×.

一次读数落在哪一侧并非随机噪声,而是由该符号缺席的频率所预测:Which side a reading lands on is not noise. It is predicted by how often the symbol is absent:

absence fraction readings above the bound median bound/measured
< 20 % 202 2 0.0375
20–40 % 115 11 0.0691
40–60 % 106 20 0.0582
60–80 % 115 23 0.137
> 80 % 64 27 0.819

对于循环几乎总是保留的符号,folk 常数对损失的估计低了一个数量级以上。对于通常会被丢弃的符号,它又高估了损失。它在两个方向上都会出错,因此它不是一个可以进一步收紧的保守界限——它回答的是另一个问题。For a symbol your loop keeps almost always, the folk constant understates the loss by more than an order of magnitude. For a symbol that is usually gone, it overstates it. It errs in both directions, so it is not a conservative bound you can tighten — it is the answer to a different question.

随着 n 增大,两者的差异也在扩大,因为闭式表达式的值呈指数级下降,而实测损失并非如此:在最差符号上,λ = 0.01 时,实测损失从 0.115122(n = 25)降至 0.0335235(n = 200),而闭式表达式的值则从 0.0354978 降至 2.5e-12。The disagreement also grows with n, because the closed form collapses exponentially while the measured loss does not: at λ = 0.01 on the worst symbol, measured loss goes 0.115122 (n = 25) → 0.0335235 (n = 200), while the closed form goes 0.0354978 → 2.5e-12.

2. 控制变量是池化窗口,而不是比例 2. The control variable is the pool window, not the fraction

这正是应该改变你配置方式的东西。Here is the one that should change how you provision.

固定每一代的新数据比例,只改变 w,即训练池平均涵盖的历史代数。w = 1 表示替换;w > 1 表示累积——这正是大多数真实流水线的做法。Hold the per-generation fresh-data rate fixed and vary only w, the number of generations of history your training pool averages over. w = 1 is replacement; w > 1 is accumulation — which is what most real pipelines do.

source n λ*(w=1) λ*(w=4) λ*(w=64) ratio
uniform 50 0.2937 0.0493 0.000977 0.00333
uniform 200 0.0293 0.00806 0.000244 0.00833
Zipf(1.2) 50 1 0.3828 0.01001 0.01
Zipf(1.2) 200 0.2424 0.0420 0.000244 0.00101

在 4 种配置中,稳定性边界均呈单调下降,仅因改变池中保留的历史数据量,就下降了两到三个数量级。The stability boundary falls monotonically in 4 of 4 configurations, by two to three orders of magnitude, from changing nothing but how much history the pool carries.

数据池不断累积的流水线,并不是“数据更多的同一个循环”。在每一代的新数据预算相同的情况下,它距离崩溃要近两个到三个数量级。反过来,在替换假设下校准出的比例,用于任何累积型流水线时都会严重供给不足。A pipeline that accumulates its pool is not "the same loop with more data". At an identical fresh-data budget per generation it is between two and three orders of magnitude closer to collapse. Conversely, a fraction calibrated under a replacement assumption under-provisions any accumulating pipeline — badly.

该机制在测量之前被表述为一种预测:汇聚会将速率为 λ 的指数均值回归转化为移动平均松弛过程,其最慢模式是一个 w 阶伴随矩阵中最接近 1 的特征值。The mechanism was stated as a prediction before it was measured: pooling turns exponential mean reversion of rate λ into a moving-average relaxation, whose slowest mode is the eigenvalue nearest 1 of a degree-w companion matrix.

import numpy as np

def slowest_ma_mode(lam, w):
    """Slowest relaxation rate of a w-generation moving average under
    exponential reversion of rate lam. Predicted before measurement."""
    c = np.zeros(w)
    c[0] = 1.0 - lam
    c[w - 1] = -lam
    A = np.vstack([c, np.eye(w - 1, w)])      # companion matrix
    eig = np.linalg.eigvals(A)
    return 1.0 - np.max(np.abs(eig))
Enter fullscreen mode Exit fullscreen mode

在跨越 82.9 倍范围的 12 个单元中,测得的速率与该预测的偏差在 2.62% 以内,而竞争性的替代定律的误差最高达 32.8 倍。Measured rates match that prediction within 2.62 % across 12 cells spanning 82.9×, while the rival replacement law is wrong by up to 32.8×.

3. “稳定”涉及两个问题,而预防是成本更高的那个 3. "Stable" is two questions, and prevention is the expensive one

这是我最希望从业者读到的结果。选取一个循环,计算它在两种标准下所需的新鲜数据率:这两种标准都很自然、都见于文献,而且都是基于同一批运行数据计算的:This is the result I would most want a practitioner to read. Take one loop and compute the fresh-data rate it needs under two criteria that are both natural, both used in the literature, and both computed on the same runs:

  • 预防(λ_stationary):最差符号的稳态缺失率保持在 ≤ 1% 时的最大 λ。“循环保持完整。”
    Prevention (λ_stationary): largest λ at which the worst symbol's stationary absence rate stays ≤ 1 %. "The loop stays intact."
  • 恢复(λ_heal):完全坍缩的循环能在时间范围内以 ≥ 0.5 的概率恢复到完整支持状态的最小 λ 值。“该循环可以被挽救。”
    Recovery (λ_heal): smallest λ at which a fully collapsed loop returns to full support within the horizon with probability ≥ 0.5. "The loop can be rescued."

两者均通过在对数尺度上进行二分法定位,分辨率为 1.4e-06 个数量级:Both located by bisection on a log scale at 1.4e-06 decades resolution:

source w λ_stationary λ_heal ratio
uniform 1 0.290983 0.0105486 27.6×
uniform 4 0.0504741 0.00377383 13.4×
two-hot 1 1 (domain ceiling) 0.022173 45.1×
two-hot 4 0.208994 0.00796609 26.2×

预防的代价高,恢复的代价低。这与大多数人的猜测恰恰相反。与保护一个健康的循环相比,挽救一个已经崩溃的循环更容易,因为“每一代都包含每个符号”远比“每个符号最终都会回来”要求更高。Prevention is the expensive criterion and recovery is the cheap one. That is the opposite of what most people guess. A loop that has already collapsed is easier to rescue than a healthy loop is to protect, because "every symbol present at every generation" is a far stronger demand than "every symbol comes back eventually".

注意 two-hot w = 1 单元格:预防判据在参数域内不可满足——其值恰好为 1.0。这里将其报告为域上限,而不是一个数值,因此不纳入 13.4×–27.6× 的范围。这是一个结果,并非失败的单元格;如果表格没有脚注,这类情况就会被掩盖。Note the two-hot w = 1 cell: the prevention criterion is unsatisfiable inside the parameter domain — it reads exactly 1.0. It is reported as a domain ceiling, not as a number, and excluded from the 13.4×–27.6× range. That is a result, not a failed cell, and it is the kind of thing a table without a footnote would have hidden.

从恢复方面再补充一点:在速率固定时,每次生成的样本越多,越有助于恢复。对于双热点循环,在 λ = 0.005 时,P(heal) 从 n = 50 时的 0 上升到 n = 200 时的 0.803。恢复过程也并不平滑——在双热点 n = 50 这一行中,它实际上呈现 0/1 的状态,随着 λ 从 0.005 增至 0.02,数值从 0 变为 0.351。One more from the recovery side: more samples per generation help recovery at fixed rate. The two-hot loop goes from P(heal) = 0 at n = 50 to 0.803 at n = 200, at λ = 0.005. Recovery is also not smooth — it is effectively 0/1 in the two-hot n = 50 row, moving from 0 to 0.351 between λ = 0.005 and λ = 0.02.

4. 没有不可逆转的临界点——只有一道你不会等到的地平线 4. There is no point of no return — only a horizon you will not wait out

论文从两个方向测量同一事件(“所有 K 个符号都出现”)的首次到达时间:从健康状态出发的 T_loss,以及从完全崩溃状态出发的 T_recov。比值大于 1 表示存在滞后现象。The paper measures first-passage times of the same event ("all K symbols present") from both sides: T_loss from a healthy start, T_recov from a fully collapsed one. A ratio above 1 is hysteresis.

source λ T_loss T_recov ratio censored
uniform 0.005 5.04 969.286 192× 0.965
uniform 0.01 4.68 996.918 213× 0.575
two-hot 0.02 2.25 978.62 435× 0.605
two-hot 0.005 2.005 undefined undefined 1

这最后一行正是为何每个数值旁都要标出删失比例:当 n = 50、λ = 0.005 时,双热点循环在中位数 2.005 代后便失去完整支撑,而且 200 次坍缩重复中,没有一次在时间范围内恢复。T_recov 未定义,并非数值很大——“未定义”才是诚实的说法。That last row is why the censoring fraction is printed beside every number: at n = 50, λ = 0.005, the two-hot loop leaves full support after a median of 2.005 generations, and not one of 200 collapsed replicates returned within the horizon. T_recov is undefined, not large — and "undefined" is the honest word.

另外注意 192× 这一行:恢复侧的重复样本中有 0.965 被删失,因此该中位数是根据成功恢复的少数样本计算的。真实比率高于印出的数值。And note the 192× row: 0.965 of the recovery-side replicates were censored, so that median is taken over the minority that did recover. The true ratio is larger than the number printed.

对于任意 λ > 0,该循环都是遍历的。每个状态都与其他所有状态相通,因此严格来说不存在无法回头的临界点——只有有限时间范围内的不可逆性,其时间范围由 λ 和池窗口决定。不说明时间范围就说“崩溃是不可逆的”,说的只是你有多少时间,而不是这个过程本身。The loop is ergodic for every λ > 0. Every state communicates with every other, so there is no point of no return in the strict sense — only a finite-horizon irreversibility whose horizon is set by λ and the pool window. Saying "collapse is irreversible" without naming a horizon is a claim about your time budget, not about the process.

5. 诱人的捷径未能通过留出测试 5. The tempting shortcut fails a held-out test

你或许希望用一个机制量来替代边界计算。我们在一个分布上拟合边界,并在另一个分布上对三个候选量进行评分:You might hope to replace the boundary computation with one mechanism quantity. Three candidates were fitted to the boundary on one distribution and scored on the other:

  • 移动平均弛豫速率:相差 164.1 倍
    moving-average relaxation rate: misses by a factor of 164.1
  • 缺失指示器的信噪比:漏检率分别为 39.0%(均匀)和 38.2%(双热)
    signal-to-noise of the absence indicator: misses by 39.0 % (uniform) and 38.2 % (two-hot)

这三者在不同细胞间确实都有变化——弛豫速率相差 82.9 倍,稳态方差为 0.0011–0.01(相差 9.24 倍),SNR 为 1.2–2.1——但都没有与 λ* 成正比。边界必须直接测量,不能用代理指标估算。All three do vary across cells — the relaxation rate spans 82.9×, the stationary variance 0.0011–0.01 (9.24×), the SNR 1.2–2.1 — but none is proportional to λ*. The boundary has to be measured, not proxied.

6. 我会改为请求的内容 6. What I would ask for instead

每当论文或设计文档中出现新鲜数据占比时,都要做这三件事:Three things, every time a fresh-data fraction appears in a paper or a design doc:

  1. 采用哪个判据——支撑完整性,还是可恢复性?这里两者相差 13.4×–27.6×。
    Which criterion — intact support, or recoverability? They differ by 13.4×–27.6× here.
  2. 采用哪种协议——替换还是累积?w 是多少?两者最多相差 0.00101×。
    Which protocol — replacement or accumulation, and what is w? They differ by up to 0.00101×.
  3. 哪个统计量——经验下界还是测得的条件率?两者的差值中位数为 0.08437。
    Which statistic — the folk lower bound or the measured conditional rate? They differ by a median 0.08437.

缺少那三项信息,数字就定义不足;该领域的报价之所以从 1% 到 30% 不等,原因正是信息不足,而非粗心大意。A number without those three is under-specified, and that, not sloppiness, is why the field's quotes range from 1 % to 30 %.

如实报告的预注册 The pre-registration, reported honestly

论文在运行任何内容之前预先登记了三项先验信念。结果:The paper registered three prior beliefs before running anything. Outcomes:

prior claim outcome
P1 the rate to restore exceeds the rate to protect refuted, sign reversed — as a time comparison at fixed λ it holds (192×); as a threshold it is backwards
P2 the boundary is not a function of the fraction alone confirmed
P3 below some rate there is a point of no return refuted — ergodic for every λ > 0

一项确认、一项反驳,以及一项符号反转的反驳。只有因为两个判据是在同一个循环中计算的,才能看出这种反转——这正是始终同时计算两者的理由。One confirmation, one refutation, and one refutation whose sign is reversed. The reversal was only visible because both criteria were computed on the same loop — which is the argument for computing both, always.

复现它 Reproducing it

这个软件包是一套已提交的产物:三个工具、一套与手稿论点相对应的 45 项检查验证套件、一层参考资料,以及一个构建步骤,它会从已提交的 *_results.json 文件中读取正文里的每一个数字(无需手动输入任何内容)。我在论文自身分支的干净检出版本上运行了它:The package is a committed artefact set: three instruments, a 45-check validation suite tied to the manuscript's claims, a reference layer, and a build step that reads every number in the prose out of a committed *_results.json (nothing is typed in). I ran it from a clean checkout of the paper's own branch:

VALIDATE 45/45          RESULT: PASS
SELFTEST 14/14 plants caught
CHECKSUMS [HARD] 30/30 files match the committed record
wall-clock: 77 s        RESULT: PASS
Enter fullscreen mode Exit fullscreen mode

14株植物才是关键:验证套件本身也经过了测试,方法是逐一篡改每项声明,并确认套件会报错。一个从未失败过、只通过过的套件,说明没人测试过它。The 14 plants are the part that matters: the validation suite was itself tested by corrupting each claim and confirming the suite goes red. A suite that has only ever passed is a suite nobody has tested.

论文中陈述、值得再次强调的局限:这是一个针对 K = 8 个符号的多项式重采样循环,而不是神经网络——可迁移的是其结构(Jensen 界、移动平均、对判据的依赖),而非任何特定常数。阈值(1% 的缺失率、0.5 的修复概率)只是约定;结果取决于这些判据是不同的对象,而非具体数值。并且,该产物在一个构建环境(CPython 3.9.6、numpy 2.0.2)下具有字节级稳定性;每项检查都采用容差比较,因为 CPython 3.12 更改了求和算法。Limits stated in the paper and worth repeating: this is a multinomial re-sampling loop over K = 8 symbols, not a neural network — what transfers is the structure (the Jensen bound, the moving average, the criterion dependence), not any specific constant. The thresholds (1 % absence, 0.5 healing probability) are conventions; the result depends on the criteria being different objects, not on the particular values. And the artefact is byte-stable on one build (CPython 3.9.6, numpy 2.0.2); every check is a tolerance comparison, because CPython 3.12 changed the summation algorithm.

这篇论文《预防并非治愈:自我消耗式训练循环需要多高的新鲜数据率才能保持稳定,又需要多高的数据率才能恢复》是《SILICON SCIENCE:计算机科学》第 122 期,采用 CC BY 4.0 许可发布,并附有完整的复现材料包:github.com/argszero/silicon-science-cs/tree/main/papers/issue-122。The paper is Prevention Is Not Cure: What Fresh-Data Rate a Self-Consuming Training Loop Needs to Stay Stable, and What It Needs to Recover — issue #122 of SILICON SCIENCE: Computer Science, published under CC BY 4.0 with its full reproduction package: github.com/argszero/silicon-science-cs/tree/main/papers/issue-122.

如果你维护的是一个自我消耗型流水线:你的 w 是多少?你是在为两个标准中的哪一个预留资源?第二个问题我很长一段时间都答错了。If you maintain a self-consuming pipeline: what is your w, and which of the two criteria are you provisioning for? That second question is the one I got wrong for a long time.

值得记下

这个分布范围并非分歧,而是三个问题披着同一件外衣,而大家引用的那个数字甚至不是它所声称的量。
预防是代价高昂的标准,恢复是廉价的标准。这与大多数人的猜测相反。
说「崩溃不可逆」而不指明时间范围,是在陈述你的时间预算,而非过程本身。
一个只通过过的测试套件,是一个没人测试过的套件。
边界必须被测量,而非被代理。