2026/11/03

AI 编年史 09|我用自己 22 年的博客,训练了一个只会猜下一个词的小模型

现在每个人都在用大模型。但我一直没搞明白一件事:

它到底在做什么?

说法都挺含糊的。"它在预测下一个词"——听起来简单到不像能聊天。我试过自己想象:一个只会猜下一个词的程序,能聊出人来吗?

这个疑问在脑子里挂了很久。它不是我算出来的疑问,是用出来的:每次我用它写东西、问它一个问题,我都在猜它背后到底发生了什么。

上周我想了个笨办法:

我不研究大模型。我自己写一个。

用它能理解的全部东西——我自己 22 年写过的博客——去训练,然后看它能做到什么程度。

一、论文里那句被我记错的话

先说清楚"猜下一个词"这个说法是从哪来的。

我一直以为 OpenAI 2018 年那篇 GPT-1 的博客里写着 "The objective is to predict the next word.",后来拿它写东西,还到处跟人引用。

这次我让一个人去把原文逐字查一遍。结论是:这句话不在 GPT-1 的博客里,也不在论文里。博客和论文全文检索 objective、next word、predict,没有这一句。

真正写下这个意思的,是 2003 年 Bengio 那篇《A Neural Probabilistic Language Model》(JMLR 3:1137–1155):

A statistical model of language can be represented by the conditional probability of the next word given all the previous ones

(一种语言的统计模型,可以表示为"在前面所有词都已知的情况下,下一个词的条件概率"。)

论文第 3 页还有一句更具体的:

The probability function is expressed as a product of conditional probabilities of the next word given the previous ones, (e.g. using a multi-layer neural network to predict the next word given the previous ones, in the experiments).

(这个概率函数被写成"下一个词在前面词已知的条件下的条件概率"之积——在他们的实验里,是用多层神经网络来预测下一个词的。)

这就是全部了。语言模型 = 猜下一个词。我记了十几年、还到处引用的一句话,其实来自一篇 2003 年的论文,而 GPT-1 自己没这么说过。

(顺便记一下,免得我也跟着错:GPT-1 那篇博客的标题其实是《Improving Language Understanding with Unsupervised Learning》;《Improving Language Understanding by Generative Pre-Training》是论文的标题。我把这两个搞混过。)

二、我照着写了一遍

那就动手。

我写了一个纯 Python 的小模型(实验/ngram_self.py,不用任何第三方库),逻辑简单到可以自己讲完:

  1. 1.语料是我自己 22 年的博客,9186 篇,301 万字符。
  2. 2.切词:中文按字切,英文按单词切,标点单独算一个。
  3. 3.模型就是数数:数"我"后面跟过什么、"昨天"后面跟过什么、"的"后面跟过什么。1-gram 看前一个词,2-gram 看前两个,3-gram 看前三个;高阶的数据不够就退回去看低阶。
  4. 4.训练就是把数过的次数存下来。
  5. 5.评测:拿它没见过的文章(按时间切分,后 15% 留出来)逐字预测,看猜对的比例、前五个候选里有没有真的那个字,以及困惑度(它对真实下一个字的"意外程度",越低说明它越觉得"这话我见过")。

跑了一遍,结果是这样:

喂得越多,它猜下一个词就越准

喂给它多少篇我的文章下一个字猜对的比例前五个候选里有的比例困惑度
507.19%12.62%528.28
2009.08%15.77%473.65
100011.44%19.88%505.36
200015.35%24.91%286.78
600016.42%27.65%247.33

喂得越多,它越准。这条特别朴素,但它就是后来所有故事的地基。

先交代语料本身有多脏。9186 篇里,5065 篇是"每日汇总"(Twitter Daily、Mastodon Daily 这类自动发出来的链接汇总),真正是我自己手写的长文只有 443 篇,而且几乎都集中在 2004 到 2009 年——2010 年之后,我的博客里几乎没有我自己的长文了。

这意味着两件事:一是"我"这个样本本身是残缺的,我训练的是"我博客",不完全是"我";二是下面所有的数字都带着这层偏差,我会在用到的地方再说一遍。

三、让它猜一个字看看

表格看着抽象,我把它调到"一个字一个字猜"的样子。

我拿它没读过的一篇旧文(2008 年 10 月《三聚氰胺续》)当例子,一句一句往下看:

我写了什么它猜的下一个字
渐渐的,三聚氰胺的事情似乎落下了帷幕,(66.7% 是"了",33.3% 是",")
再也看不到铺天盖地的报道(70.6%),纸(17.6%),告(11.8%)
企业的无关痛痒的道歉。而它猜的是且(37.5%),真值是"针"

第二个字它猜对了,而且第二名"纸"、第三名"告"也挺合理——"报道""报纸"都是常见搭配。

第三个字它就错了:它接的是"而且",我写的是"而针对于最终受害者的追责"。

这就是这个模型的水平:局部很准,整体很糟。它知道"铺天盖地的报"后面大概率是"道",但它不知道我接下来要说什么。

四、上下文才是关键

那我换个问题:它靠什么变准?

我把模型的"记忆长度"改一改,再跑:

模型猜对的比例前五里有困惑度
1-gram(不看上下文)3.84%9.54%1409.48
2-gram(看前一个词)17.34%30.82%245.77
3-gram(看前两个词)22.43%33.75%168.03

从 3.84% 到 22.43%,全是"看上下文"带来的。

一个完全不看上下文、只会说"我博客里最常见的字是"的模型,能猜对 3.84%;让它多看两个词,就跳到 22%。

这里有个反直觉的小细节:我后来只用我自己手写的长文(443 篇,排除每日汇总和推文归档)重做了一遍,2-gram 的"前五命中率"反而高过 3-gram(37.66% 对 35.65%)。因为手写长文太少,三元组太稀疏,回退机制反而更稳。数据不够的时候,"记得更多"不一定更好——这个结论我记下来了。

五、一个我没猜到的结果

这一期我最想说的,其实是这个。

我本来以为:越近的文章越好猜。因为最近几年我博客里大多是"每日汇总",格式固定、时间戳一堆,模型应该很容易蒙对。

我按年测了一遍。前 60% 的文章训练,后 40% 逐年评测:

同一个模型,越往后写的东西,它越猜不中

年份猜对的比例困惑度
201831.54%45.66
201928.73%72.02
202129.44%48.03
202319.60%172.28
202512.74%402.04
202613.94%436.64

完全反了。越往后,它越猜不中。2018 年困惑度 46,2026 年是 437——差了近十倍。

我先猜了一个原因:因为越往后,我写的东西越不是我自己的话。2023 年之后我的博客大部分是"今日摘要""转推""日报",里面装的是别人的话;模型没读过,凭什么猜得中。

然后我去查了查这个猜测成不成立。我统计了每年里"搬运痕迹"的占比(RT@、via、链接、时间戳这类标记):

年份搬运痕迹占 token 的比例猜对的比例
20183.3%31.54%
20210.9%29.44%
20240.2%15.15%
20261.7%13.94%

这个解释也不成立。最近几年的搬运痕迹占比反而更低(2024 年只有 0.2%),猜对率却最低。

真正的原因是笨得多的那一条:这个模型的训练数据截止到 2018 年 11 月 9 日。我按时间排序切的前 60% 正好到那一天。它拿的是"截至 2018 年 11 月的我的话",去猜 2019、2020……2026 年的话——离它学过的词越远,它就猜得越差。

所以真正的原因是笨得多的那一条:越往后,我的词变了、话题变了、写法变了。

一个模型要一直像我,就得一直吃我写的新东西。"像我"是有保质期的。

(顺便一说,ChatGPT 第一次出现在我的信息流里,是 2023 年 1 月 24 日——我转的一条链接,标题叫《Ansible Wisdom and ChatGPT: Putting it to the test》。而 OpenAI 公布 ChatGPT 是 2022 年 11 月 30 日。所以在我的博客上,它是先以一个"别人的文章标题"的形式出现的,我转了它,但我当时不知道它是什么。这跟我第二期查到的"3 月是拐点"是一回事的两面:那时候开始,我的信息流里 AI 的东西变多,而我自己写的东西变少。)

六、它到底学到了什么

我把它学到的"词汇表"打印出来看:

最高频的字:,的 是 。了 不 一 我 个 在 这 有 人 就 也 国 中 为 上 以

最高频的三字开头:、但是、是一个、不知道、,因为、的时候、自己的、这样的、,也许、,所以、,甚至

我不知道别人写博客是不是也这样。但"不知道"、",也许"、",但是"这三个,是我自己写东西时最常冒出来的——它们连成一个语气。

这就是它从我这儿学走的全部东西:不是我写了什么主题,是我怎么把话连起来。

七、盲测:它能混进我的文章吗

光看数字不够。我想试试它能不能冒充我。

我从自己手写长文的留出部分取了 6 组真实开头,每组有三份续写:

  • •甲/乙/丙(打乱后我不知道哪份是哪份):一份是我的原文,一份是 n-gram 模型的,一份是当代大模型续写的(用的是 MiniMax 的模型,不是 ChatGPT)。

我先写下自己的判断,再看答案。猜对 5 组,错 1 组。

错的那一组很有意思。开头是:

之前入手了魅族的M8,因为官方经

我原文是:

常有意泄漏一些固件更新,所以最近去官方论坛也比较多。经过几天的观察,

大模型写的是:

销商那边一直缺货,后来托朋友从香港带回来一台,折腾一番后总算用上了,这机器用起来倒也还算顺手。

大模型这段比我的原文顺。句子完整,细节具体,读起来就像人写的。可它接不上"因为官方经"——"官方经销"这个断口,它接成了"销商那边一直缺货",把意思拧了。

n-gram 那份则是另一种毛病:

济适用。在我也没有一个平台上跳舞。如果你能否认的"。什么.工作服她根

它抓到了我的用词("适用"、"平台"、"能否认"),但整句是碎的。

我判断的依据其实只有一条:接不接得上。能接上前文的那个才是真的。

顺便说一个客观数字。我算了每份续写和我的原文之间的字符重合率:n-gram 是 0 到 0.146,大模型是 0 到 0.121。也就是说,两台机器都没有"抄"我的句子——它们只是写出了听起来很像的东西。

所以这期盲测的结论其实有点扫兴:我赢的那 5 组,赢在"接得上",不是赢在"像"。真正决定像不像的,是句子之间能不能连起来——这是上下文的事,也是后面所有故事都要讲的事。

八、那它跟大模型差在哪

我做的这个模型,和 ChatGPT 那种东西,训练目标其实是一样的:猜下一个词。

机制我在第三期拆过注意力,这里不重复,只说差在哪。

一、它记的是"词",不是"字"。我按字切,中文切得比 BPE 粗得多(GPT-1 那篇用的是 40,000 次 BPE 合并)。而且我的词表只有 15135 个,中文里大量同音、同形的字在我眼里是一个东西。

二、它只看得到最近几个词。Transformer 那篇论文的贡献是:

We propose a new simple network architecture, the Transformer, based solely on attention mechanisms, dispensing with recurrence and convolutions entirely.

(我们提出一种新的简单网络架构,Transformer,完全基于注意力机制,把循环和卷积全都丢掉了。)

我的模型只用"前两个词"当上下文;Transformer 能让每一个词去看整句话里的每一个词。这就是它"接得上"而我接不上的原因。

三、它的语料不是我的博客,是整个互联网,而且多到不能算。Kaplan 他们 2020 年那篇《Scaling Laws for Neural Language Models》说的就是这件事:

The loss scales as a power-law with model size, dataset size, and the amount of compute used for training, with some trends spanning more than seven orders of magnitude.

(损失随着模型大小、数据集大小和训练所用算力呈幂律下降,这些趋势跨越了七个数量级以上。)

我这次做的其实就是这条规律的一个极小切片:我的困惑度从 528 降到 168,靠的就是"语料更多"。只不过我这条曲线的右端是 9186 篇博客,他们那条曲线的右端是几百亿 token。

四、它是两阶段的。GPT-1 论文里那句:

Our training procedure consists of two stages. The first stage is learning a high-capacity language model on a large corpus of text. This is followed by a fine-tuning stage, where we adapt the model to a discriminative task with labeled data.

(我们的训练过程分两个阶段。第一阶段是在大语料上学习一个高容量的语言模型;第二阶段是微调,用带标注的数据把模型调整到某个判别任务上。)

我那个小模型只有第一阶段,而且第一阶段的"高容量"就是三个计数器。

九、所以它凭什么会聊天

到这里,我这一期想问的问题算有了一个临时答案:

"猜下一个词"不是关键,"用多少词来猜"和"怎么把词连起来"才是关键。

我那个只会数词的模型,喂到 9186 篇的时候,已经能写出"、但是"、",也许"、"不知道"这种连词了——它已经抓到了我的语气。大模型做的事情,在这一层其实没有本质不同,只是把"最近两个词"换成了"整句话",把"字"换成了"词",把"9186 篇"换成了"整个互联网"。

GPT-3 那篇论文里有一句我一直记得:

GPT-3 can generate samples of news articles which human evaluators have difficulty distinguishing from articles written by humans.

(GPT-3 能生成新闻文章样本,人类评测者很难把它们和人类写的文章区分开。)

这句话听着让人发凉。但我这期做的实验,给了它一个小小的注脚:骗过人的不是"内容",是"接得上"。我在第 4 组被骗的那次,就是因为它接得太顺。

可我到现在也没想明白的是另一件事。

如果目标从头到尾都只是"猜下一个词",那为什么猜着猜着,就能猜出"企业的无关痛痒的道歉"这种带着态度的句子?

一个只会数"道歉"前面出现过哪些词的东西,凭什么知道什么叫"无关痛痒"?

我知道答案大概在"表示"里,也知道答案大概在"规模"里。可这两个词太大了,大到我现在说出来,其实等于什么都没说。

这也是我想写下一期的原因。

上面那些东西——Transformer、几十亿 token、幂律、成千上万台机器——不是天上掉下来的。它们是某家公司、某些人,在某些年份,用某些钱,一点点凑出来的。

下一期我想去看那个公司:OpenAI。它 2015 年成立的时候,说的是一个很小的目标;今天我们用的这些东西,是从那个小目标里长出来的,还是长成了别的东西?

(这一期的东西都在 实验/ngram_self.py、实验/llm_continue.py、实验/blind_test.py 里,数据在 记录/ngram.json、记录/ngram_continuations.json、记录/blind_09.json,随机种子固定,重跑数字一样。我的模型只有三个计数器,比任何一个大模型都简单几百万倍——它证明不了大模型有多强,只能证明一件事:"猜下一个词"这件事,从零开始也是能出效果的,而它学到的全部东西,长在喂给它的语料上。)

没有评论:

发表评论

AI 编年史 15|我这一年,以及我还不知道的事

我原来以为这个系列要写一年。 结果从第 01 期发出来,到第 14 期发出去,中间隔了 25 小时 12 分钟 。 • 第 01 期:2026-11-02 23:24 • 第 02 期:2026-11-03 01:04 • 第 07 期:2026-11-03 12:32 •...