从林语堂的明快打字机到大模型的 token 词表

你打开 ChatGPT,粘进一段中文,发现 token 用量常常比同等意思的英文更高。名义上是 1M 的上下文窗口,真正能装下的中文材料,可能明显少于英文材料。
这听起来像是大模型时代的新问题。但八十年前,林语堂面对过它的另一个版本。
1947 年,他试图把几万个汉字塞进一台接近西方打字机尺寸的机器里。明快打字机只有 72 个键。打字员不是按一个键直接打出一个字,而是先按"上形"键,再按"下形"键,最后在一个被称为"魔术眼"的窗口里从候选字中选择目标字。打字这件事,被林语堂改造成了"检索 + 选择"。
一个是机械打字机,一个是大模型 API;一个发生在 1947 年,一个发生在 2026 年。它们表面上毫不相干,背后却是同一个问题:
中文必须一代又一代地装进只能放下有限单元的信息系统。
键盘只有几十个键。Unicode 早期只规划了 16 位码点空间。UTF-8 让中文每个字符占 3 字节。tokenizer 词表通常在十几万到二三十万量级。每一代技术都声称自己解决了问题;下一代会发现,问题没有消失,只是被搬到了一个新的层面。
这就是本文想讨论的"代价守恒"。
所谓代价守恒,不是说成本总量严格不变,而是说:当一个表示系统把中文问题在某一层压平时,复杂度往往会转移到另一层。它可能从用户手上转移到机器里,从显性的输入动作转移到编码空间,从字节成本转移到 token 成本,最后转移到神经网络内部那些不容易被看见的表征偏差。
这条线可以分成四层:
- 键盘层:几十个键如何输入几千到几万个汉字
- 编码层:有限码位如何容纳全球文字
- Tokenizer 层:有限词表如何切分中文
- 神经网络表征层:模型内部如何继承 tokenizer 的偏差
四代技术,四个房间,同一个矛盾。
一、键盘层:从按键到检索
物理键盘是这个矛盾的第一站。
英文打字机的基本逻辑很简单:按下一个键,纸上出现一个对应字符。键盘上的字母数量和英文书写系统的基本单位大致匹配,所以"按键 = 印字"可以成立。
中文不能这样做。常用汉字以千计,完整字符集以万计。无论键盘有几十个键还是上百个键,都不可能让每个汉字获得一个专属按键。于是中文打字从一开始就不是"直接映射"问题,而是"有限按键如何检索庞大字符集"的问题。
1947 年,林语堂的明快打字机给出了一个早期答案。
当时主流中文打字机多采用大字盘方案:机器上排布大量铅字,打字员通过机械臂从字盘中寻找目标字,再把它打到纸上。这种方案可用,但效率低、训练成本高,也很难达到英文打字机的速度。
明快打字机选择了另一条路。它没有试图把每个汉字都放到键盘上,而是用 72 个键构造了一套检字系统。打字员通过"上形键"和"下形键"描述目标字的形状,再从"魔术眼"窗口中出现的候选字里选择。按键不再直接对应字符,而是对应检索路径。
林语堂真正改变的不是某个机械部件,而是中文打字的范式:打字不再是"按键 = 印字",而是"按键 = 检索 + 选择"。
更重要的是,他主动绕开了传统部首检字法。康熙字典式的部首体系适合纸面查字,但并不适合机械输入。部首分类有大量历史沉淀和例外规则,很多时候并不能直接变成高效的机械索引。明快采用的是更接近几何形状的检字方式:把字形拆成可以被键盘编码的上、下形结构,用形状而不是传统语义部首来组织输入。
明快最终没有量产——价格、资金、政局多重因素叠加,使它停留在原型机阶段。但它的意义没有消失:你按下的键不再是汉字本身,而是用来定位汉字的线索。这个范式,后来在五笔中以软件形式重演。
1980 年代,王永民面对的是新的约束:QWERTY 键盘已经成为全球事实标准,中文输入必须在标准键盘上完成。五笔字型的方案是把汉字拆成字根,再把字根分布到字母键上。标准键盘有 26 个字母键,五笔通常使用其中 25 个,把 Z 键留作功能键或万能键。
五笔的核心不是拼音,而是字形。王永民根据汉字部件的出现频率和可拆性设计字根表,把字根分配到横、竖、撇、捺、折五个区。一个汉字最多敲四个字母,系统就能直接命中或给出极少候选。熟练用户可以达到很高速度,专业打字员甚至能接近或超过英文打字员的输入效率。
但五笔把代价放在了用户身上。它很快,但难学。用户需要记字根、练拆字、形成肌肉记忆。对专业打字员来说,这是一种可以通过训练换取效率的技能;对普通用户来说,它是一道很高的门槛。
后来真正普及的,是拼音输入法。拼音输入法选择了相反方向:不要求用户学习新的字根体系,而是利用大多数中文用户已经掌握的拼音知识。用户输入声音线索,系统负责从海量同音字、词、句中推断目标内容。
这条路的代价不在用户,而在系统。早期拼音输入法依赖词典和规则,整句输入不稳定,经常需要用户二次修正。后来,大规模语料、词频统计、n-gram 模型、互联网热词、云端词库、个性化排序陆续进入输入法。到了搜狗拼音之后,输入法已经不再只是单机软件,而是一个持续吸收互联网数据、更新词库、适应用户习惯的统计推理系统。
用户感受到的是:“拼音越来越好用。“但这种好用背后,是复杂度的迁移。
明快、五笔、拼音输入法看似是三种完全不同的方案,其实处理的是同一个约束:用几十个键输入几千到几万个汉字。
明快把复杂度放进机械结构里;五笔把复杂度放进用户记忆里;拼音输入法则把复杂度放进词库、语言模型、云端更新和个性化排序里。
用户的负担一代比一代轻,系统的负担一代比一代重。
这是代价守恒的第一种形态:体验变轻,系统变重。
二、编码层:从乱码到字节税
键盘层解决的是"怎么把汉字打进机器”。编码层面对的是更深的问题:机器内部究竟如何表示这些汉字。
早期计算机的底层默认并不是中文。ASCII 在 1960 年代形成,采用 7 bit 编码,共 128 个字符,足够表示英文字母、数字、标点和控制字符。它后来成为全球计算基础设施的重要默认之一,但在诞生时,它解决的是英语信息交换问题。中日韩文字并不在它的设计范围内。
这不一定来自某种明确的排除决定,更像是基础设施默认值的自然后果:设计者解决的是自己眼前的语言问题,而不是全球文字系统的问题。等计算机真正全球化时,中文、日文、韩文才发现自己必须以"扩展"的方式进入系统。
于是各地区开始各自扩展。中国大陆有 GB 2312,台湾地区有 Big5,日本有 Shift-JIS,韩国有 KS X 1001。它们在各自区域内能够工作,但跨地区交换时,问题立刻出现。同一串字节,在一个系统里是一段正常中文,在另一个系统里可能就是乱码。1990 年代到 2000 年代初的中文互联网用户,大多都经历过乱码邮件、乱码网页和无法正确显示的文件名。那不是内容坏了,而是发送方和接收方对同一串字节采用了不同解释方式。
Unicode 的出现,就是为了解决这种字符集分裂。
1990 年代初,Unicode / ISO 10646 试图把全球文字统一进一个码点空间。它的理想很清楚:每一个字符都有一个全球唯一的码点。中文、日文、韩文中的汉字被放入 CJK Unified Ideographs,基本区位于 U+4E00 到 U+9FFF,经过多轮扩充共收录两万余个汉字(其中早期主体部分大体沿用康熙字典的部首-笔画顺序)。
这一步极其重要。它让不同地区、不同系统、不同软件终于有机会在同一张字符表上对话。乱码问题没有立刻消失,但至少在字符集层面,世界开始拥有共同语言。
然而,统一字符集不等于成本消失。
首先出现的是码点空间压力。Unicode 早期曾经受到 16 bit 视野影响,65,536 个码位看起来很多,但面对全球文字、符号、历史文字、扩展汉字,很快就不够。后来 Unicode 扩展到更大的码点空间,通过平面、代理项等机制处理基本多文种平面之外的字符。中文和其他 CJK 字符,是推动这套空间扩张的重要压力来源之一。
更直接的成本,则出现在字节编码层。Unicode 定义的是码点,真正落到文件、网络和数据库里,还需要编码成字节流。UTF-8 成为今天最主流的文本编码之一,它的设计非常优雅:ASCII 字符保持 1 字节,以兼容早期系统;其他字符则使用 2 到 4 字节表示。
这种设计保住了英文世界的历史兼容性,也让中文承担了更高的字节长度。ASCII 英文字母在 UTF-8 中通常是 1 字节,常用汉字通常是 3 字节,部分罕见汉字和 emoji 可能是 4 字节。于是,在大量以 UTF-8 为默认、按字节限流、按字节计费、按字节切分的系统里,中文会更早碰到边界。
类似现象在短信时代已经出现过。传统英文短信可以容纳 160 个 GSM 7-bit 字符,而中文短信通常只能容纳 70 个字符(UCS-2 编码)。这里的具体机制不是 UTF-8,但结构是一样的:当底层表示单元不是为中文优化时,中文会更早撞到系统边界。
编码层解决了"读不懂"的问题,却没有让所有文字在基础设施中的成本变得相等。GB、Big5、Shift-JIS 时代,问题是字符集之间互不兼容;Unicode 之后,世界终于开始使用同一张表,但中文在字节层面的表示成本仍然留了下来。
乱码消失了,税还在。
三、Tokenizer 层:从字节税到 token 税
大模型时代,中文的表示矛盾从存储层转移到了 tokenizer 层。
大模型并不直接处理我们理解中的"字符”。文本会先被切成 token,再被映射成整数 ID,送入神经网络。token 是模型看到文本的基本单位。上下文窗口、API 计费、推理成本、注意力计算,很多都围绕 token 展开。
于是,中文开始支付一种新的成本:token 成本。
GPT-2 在 2019 年首次大规模采用 byte-level BPE 作为 tokenizer。它的基本思路是先把文本视为字节序列,原子单位不是具体字符,而是 256 个可能的字节值。这样做的好处是鲁棒:任何 Unicode 字符都能被表示,不会出现真正的 OOV,也就是 out-of-vocabulary。
BPE 随后在字节序列上继续工作,根据训练语料中的频率,把常见字节对合并成更长 token。英文中的高频单词、词根、空格加单词组合,会逐渐被合并成稳定 token;低频片段则保留为更细的子词或字节片段。
这个设计的出发点不是中文,而是通用性和鲁棒性。但它把 UTF-8 的历史包袱带进了大模型。ASCII 英文字符通常是 1 字节,常用汉字通常是 3 字节。如果训练语料和词表合并主要围绕英文展开,很多中文字符就不会被稳定合并成一个 token,而会被拆成多个 token。于是,同样的信息量,中文可能消耗更多上下文窗口。
在许多英文默认的 tokenizer 上,中文 token 数确实经常高于同等含义的英文。具体比例取决于内容类型、模型词表和文本风格。新闻、法律、技术文档、口语对话之间差异很大;GPT-4 的 cl100k_base、GPT-4o 的 o200k_base,以及 Anthropic、Meta 等模型的 tokenizer,对中文的处理也并不相同。但总体趋势很清楚:如果 tokenizer 的词表主要由英文语料塑造,中文往往会更碎。
更碎意味着账单更高、上下文容量更小、长文档更早撞到窗口边界。对总结、问答、检索增强、合同分析、学术资料处理来说,这不是抽象的语言公平问题,而是直接影响产品体验的工程事实。
中文友好的 tokenizer 试图反过来解决这个问题。一些中文优先或多语言优化更激进的模型,会把常用汉字、高频中文词组甚至常见短语纳入词表。一个汉字可以对应一个 token,高频词组也可以直接成为 token。这样一来,中文 token 数明显下降。在某些情况下,中文甚至可能比英文更省 token。
这看起来像是问题终于被解决了,但新的代价随之出现。
当一个汉字被合并成单个 token,模型输入端看到的是一个不透明的整数 ID,而不是组成它的 UTF-8 字节序列。对模型来说,“茶"可能只是某个 token ID;它不再天然暴露出这个字在字节层面与其他相邻汉字共享的结构。
这里存在一个容易被忽视的结构性巧合。CJK Unified Ideographs 基本区的早期主体大体按康熙部首-笔画排序,因此同部首汉字在码点空间里存在一定聚集。UTF-8 又会把相近码点映射成相近的字节序列。byte-level BPE 在这些字节序列上做频率合并时,一些共享部首或处于相近码点区域的汉字,就可能共享相同或相近的前缀 token。
这不是 Unicode、UTF-8 或 BPE 的设计者有意为大模型保留的"字形通道”,而是三个独立设计叠加后的副作用:字符排序保留了一部分部首结构,变长编码把码点邻近性转化为字节邻近性,BPE 又把高频字节片段合并成 token。于是,在一些多 token 汉字中,模型可能通过字节片段间接接触到字形和部首结构。
这条通道并不稳定,也不总是可靠,但它可能确实存在。当 tokenizer 为了降低中文 token 成本,把常用汉字整体合并成单个 token 时,token 数下降了,账单变便宜了,上下文变大了;同时,字节级结构信号也被压扁了。
大多数日常任务里,这个代价不明显。模型仍然可以通过字典解释、教材文本、语料共现、字形分析文章等方式学习部首知识。它并不一定非要依赖字节通道。但当任务落到字形、部首、生僻字、细粒度语义相似度判断时,这条被压扁的通道可能重新变得重要。
Tokenizer 层的矛盾正在这里显现:短 token 让中文更贵,长 token 让中文更便宜;但长 token 也可能把某些结构信号封进不透明的 ID 里。代价没有消失,只是从账单和窗口,转移到了表示结构本身。
四、神经网络表征层:代价变得不可见
到了神经网络表征层,问题变得更难观察。
键盘层的代价可以数按键次数,编码层的代价可以数字节,tokenizer 层的代价可以数 token。可是模型内部的表征偏差,既不会出现在账单上,也不会显示在上下文窗口旁边。它藏在神经网络的表示空间里,只有在精心设计的实验中才会显形。
David A. Haslett 在 2025 年发表于 Computational Linguistics 的论文《Tokenization Changes Meaning in Large Language Models: Evidence from Chinese》,正是这样一个实验。
这篇论文关心的问题很直接:tokenizer 的切分方式,是否会改变大模型对中文字符意义的判断?
如果只是直接问模型"你懂不懂部首",答案没有太大意义。模型可能记住了字典知识,可能从语料共现中学到了一些字形关系,也可能只是被 token 结构误导。Haslett 的巧妙之处,在于利用部首和 token 之间的不完美对齐,把两种信号拆开。
有些汉字真实共享部首,也共享首 token;有些汉字真实共享部首,但不共享首 token;有些汉字不共享部首,却共享首 token;还有些汉字两者都不共享。这样一来,当模型判断两个汉字是否共享部首时,研究者就能区分它到底是在使用真实的部首知识,还是在被 token 相似性牵引。
实验结果显示,两件事同时成立。
一方面,模型确实学到了部首知识。 即使两个字不共享 token,只要它们真实共享部首,模型回答"是"的概率仍然显著更高。这说明模型并不是只靠 token 猜答案,它确实从训练数据中获得了某种关于部首、字形和汉字结构的知识。
另一方面,token 信号也会制造偏差。 当两个字真实部首不同,但共享某个 token 片段时,模型仍然更容易判断它们共享部首。换句话说,token 相似性会被模型误当成某种结构或语义相似性。两个本不该被归为一类的字,仅仅因为 token 切分上的重合,就可能在模型判断中被拉近。
这说明 tokenizer 并不是一个中性的预处理工具。它不只是把文本压缩成整数 ID,而是会把自己的切分痕迹带入模型的表示系统,影响模型如何理解字符之间的关系。
Haslett 进一步用多组实验排除替代解释。他把任务从"是否共享部首"换成语义相似度判断,观察 token 效应是否只是由 prompt 中的"部首"一词诱导出来;他把题型改成 odd-one-out 离散选择,排除连续打分方式带来的偏差;他比较单 token 字符和多 token 字符在部首识别上的表现,发现多 token 字符在某些部首任务上反而更容易被模型正确处理;他还把实验扩展到 12 种欧洲语言中的后缀现象,说明这种 tokenization bias 并不是中文独有。
这组实验真正重要的地方,不只是证明"大模型会受 tokenizer 影响"。更关键的是,它说明这种影响并没有停留在输入层或嵌入层,而是可以渗透到模型的语义判断中。token 不只是压缩文本的工程单位,也可能成为模型理解语言结构时的一条隐性捷径。
这对中文尤其有启发。byte-level BPE 中的多 token 汉字虽然更贵,却可能保留了一些字节级结构信号;整字 token 化降低了中文 token 成本,却把这些结构信号封装进一个不透明 ID。模型仍然可以通过训练数据学习部首知识,但它少了一条潜在的隐性通道。
这就是"长 token 不免费"的含义。
它的好处非常直接:更少 token,更低成本,更长上下文。它的代价却更隐蔽:某些结构信号被压扁,某些细粒度判断可能变得更依赖显式训练数据,而不是底层表示中残留的形态线索。
目前还不能简单断言哪条路线一定更好。如果 Qwen、DeepSeek 等中文友好 tokenizer 在部首识别和字形任务上表现很好,那说明显式知识足以补偿字节通道的关闭,整字 token 化就是非常合理的工程选择。如果它们在某些细粒度字形任务上明显弱于保留多 token 字节结构的模型,那就说明 tokenizer 优化不能只看 token 数,还要考虑结构信号的保留。
公开研究还不够充分,这个问题仍然开放。但 Haslett 的论文至少已经把矛盾推进到了新的层面:中文的表示代价不再只是"多花几个 token",也不只是"上下文窗口少装一些内容"。它可能进入模型内部,改变模型如何组织字形、部首和语义之间的关系。
代价在这里变得不可见了。它不再表现为按键次数、字节数或 token 数,而是变成了一种表征偏差,藏在模型判断的边界处。
五、中文不是例外,而是放大镜
回头看这四代技术,会发现它们处理的其实是同一个问题。
中文是一套庞大、开放、结构复杂的书写系统,而信息技术总是在某一层设置有限表示单元:有限按键、有限码位、有限字节、有限词表、有限向量维度。每一代工程师都在做同一件事:把几千到几万个汉字,塞进一个更小、更规整、更适合机器处理的表示系统里。
键盘层的答案是检索。 明快、五笔、拼音输入法都没有让每个汉字拥有自己的按键,而是把输入变成"有限线索 + 候选选择"。明快用机械结构完成检索,五笔用字根编码完成检索,拼音输入法用语言模型和词频排序完成检索。
编码层的答案是统一。 ASCII 没有为中文留下空间,各地区编码各自扩展,导致乱码和不兼容。Unicode 把全球文字统一进一个码点空间,解决了字符集分裂问题,却没有让不同文字在字节基础设施中的成本完全相等。
Tokenizer 层的答案是压缩。 byte-level BPE 用字节作为原子单位,保证任何字符都能表示,但在英文默认的词表里,中文往往被切得更碎。中文友好的 tokenizer 通过整字、整词、短语合并降低 token 数,却可能封闭某些字节级结构信号。
神经网络表征层的答案还不清楚。 模型可以通过训练数据学习部首、字形和语义关系,也可能通过 tokenizer 残留的字节结构走捷径。Haslett 的实验说明,这些捷径既可能有用,也可能误导模型。tokenizer 的切分方式不只是影响输入长度,也可能影响模型内部的语义组织。
这件事当然不是中文独有的。任何不是英语的语言,都在以不同方式支付"非默认语言的基础设施税"。只要一套基础设施以某种语言为默认,其他语言就会被放到"扩展"“兼容"“特殊处理"的位置上。
中文的特殊性在于,它把这个问题放大到了极致。它的常用字符数量远超字母文字,字形结构复杂,既有语义部件,也有声旁、形旁、历史演变和简繁差异。更重要的是,它在现代信息技术史中持续存在,从机械打字机、字符编码、输入法、搜索引擎,一直延伸到大模型 tokenizer。
从林语堂的明快打字机到今天的大模型 token 词表,中文一次次倒逼信息技术修改自己的表示方式。每一次修改都带来新的解法,也带来新的代价。
六、问题只是搬到了新的房间
四代技术,四个层面,同一个矛盾。
键盘层面对的是"几十个键如何输入几万个字”。明快、五笔、拼音输入法的答案不同,但方向一致:把直接输入改造成检索和选择。代价从机械结构转到用户记忆,再转到词库、模型和云端系统。
编码层面对的是"有限码位如何表示全球文字”。Unicode 解决了各地区编码互不兼容的问题,但在 UTF-8 这样的主流编码里,中文仍然在许多按字节计算的系统中承担更高成本。
Tokenizer 层面对的是"有限词表如何切分中文"。byte-level BPE 解决了 OOV,却把 UTF-8 的字节结构带进模型;中文优化 tokenizer 降低了 token 成本,却可能封闭某些字节级结构信号。
神经网络表征层面对的是更隐蔽的问题:tokenizer 的选择不只是影响账单和上下文长度,也可能影响模型内部如何理解字形、部首和语义关系。到了这一层,代价不再直接显示在按键次数、字节数或 token 数上,而是藏进模型的表征里,只有通过精心设计的实验才能看见。
下一代解法可能来自多模态模型,直接处理字形;可能来自字符级或字节级架构,绕开现有 BPE;也可能来自尚未被命名的新表示层。我们暂时无法预测它的具体形态,但可以预测的是,新的表示方式仍然会遇到旧问题。
每一代都以为自己给出了答案。下一代会发现,答案只是把问题搬到了一个新的房间。
这场对话还会继续。
主要参考
- David A. Haslett, “Tokenization Changes Meaning in Large Language Models: Evidence from Chinese,” Computational Linguistics, 51(3): 785–814, 2025.
- Thomas S. Mullaney, The Chinese Typewriter: A History, MIT Press, 2017.
- C.C. Sun et al., “Chinese Lexical Database (CLD): A Large-Scale Lexical Database for Simplified Mandarin Chinese,” Behavior Research Methods, 50(6): 2606–2629, 2018.
- Unicode CJK Unified Ideographs block, U+4E00–U+9FFF.