• 完整学习LLM(四):Token是什么


    完整学习LLM(四):Token是什么

    好家伙,

    上一篇我们聊了:

    为什么大模型是在预测下一个 token.

    当时一直在说 token.

    但其实还有一个问题没有拆:

    Token 到底是什么?

    这个词在大模型里出现得太频繁了.

    比如:

    上下文窗口是多少 token
    输入 token 怎么计费
    输出 token 怎么计费
    这个模型最多支持多少 token
    为什么一句中文和一句英文 token 数不一样

    如果不理解 token,后面看上下文窗口、Embedding、Prompt、计费、RAG 切块都会有点虚.

    所以这篇就单独聊它.

    还是老规矩:

    不先上复杂算法.
    先用项目里能碰到的问题解释.

    0.背景:为什么不能直接把一句话丢给模型

    我们平时看到的是文字.

    比如:

    我想学习大模型和 RAG

    但模型本身不能像人一样直接"看懂"这句话.

    计算机最终处理的是数字.

    所以文本进入模型之前,要先经历一个转换过程:

    文本
    -> 切成 token
    -> token 转成编号
    -> 编号转成向量
    -> 进入模型计算

    也就是说:

    Token 是文本进入模型前的中间单位.

    它不是最终的向量.

    也不是我们看到的完整句子.

    它更像是模型能处理文本之前,先把文本切成的一小块一小块.

    Token切分流程

    1.Token不是简单等于一个字

    很多人第一次理解 token,会直接想成:

    一个 token = 一个字

    这个理解不完全对.

    有时候一个字可能是一个 token.

    有时候一个词可能是一个 token.

    有时候一个英文单词会被拆成多个 token.

    有时候标点、空格也会影响 token.

    比如英文:

    unbelievable

    它可能不是一个整体.

    可能被拆成类似:

    un
    believ
    able

    再比如:

    ChatGPT

    也可能被拆成不同的小块.

    中文也一样.

    大模型

    可能作为一个整体处理.

    也可能被拆成:

    模型

    具体怎么拆,取决于模型使用的 tokenizer.

    所以先记住一点:

    Token 是模型的文本切分单位,但不一定等于一个字或一个词.

    2.为什么要切成Token

    原因很直接:

    模型需要把文本变成可计算的数字.

    如果不切,整篇文章就是一大坨字符串.

    模型没法直接算.

    切成 token 以后,每个 token 可以映射成一个 ID.

    比如粗略想象:

    我 -> 1024
    想 -> 358
    学习 -> 9012
    大模型 -> 7718
    RAG -> 64001

    这些 ID 再进入下一步,变成向量.

    向量才是模型真正能计算的东西.

    所以 token 的作用有点像:

    把人类文字拆成模型能查表、能编码、能计算的基本块.

    如果没有 token 这一步,模型就不知道怎么把文本稳定地送进计算流程.

    3.Token和预测下一个Token的关系

    上一篇说过:

    大模型是在预测下一个 token.

    现在就更好理解了.

    因为模型看到的不是:

    我想学习大模型

    而是一串 token:

    [我] [想] [学习] [大模型]

    它要做的是:

    根据前面的 token,
    预测后面最可能接哪个 token.

    比如前面是:

    我 想 学习

    后面可能接:

    大模型
    Python
    RAG
    Docker
    英语

    模型会根据上下文算这些候选的可能性.

    然后选择一个继续生成.

    所以:

    Token 是输入单位.
    也是输出单位.

    用户输入会被切成 token.

    模型回答也是一个 token 一个 token 生成出来的.

    4.Token为什么会影响上下文窗口

    我们经常看到一个说法:

    某个模型支持 128k 上下文.

    这里的 128k,通常说的就是 token 数.

    不是 128k 个汉字.

    也不是 128k 个单词.

    这点很重要.

    因为模型的上下文窗口限制的是:

    最多能放进去多少 token.

    比如一个模型最多支持:

    8192 tokens

    那你输入的内容、系统提示词、历史对话、检索出来的资料、模型要输出的答案,都要挤在这个窗口里.

    大概可以想成:

    系统提示词
    用户问题
    历史对话
    RAG 检索片段
    工具返回结果
    模型输出

    这些加起来都占 token.

    所以做 RAG 的时候,不是把文档全塞进去就完事.

    因为文档太长,token 会爆.

    这也是为什么 RAG 要做文档切块.

    5.Token为什么会影响成本

    大模型 API 通常会按 token 计费.

    一般分成:

    输入 token
    输出 token

    输入 token 是你发给模型的内容.

    输出 token 是模型生成的内容.

    比如:

    Prompt 很长
    历史对话很多
    RAG 检索片段塞太多
    模型回答很啰嗦

    都会让 token 数上升.

    token 数上升以后,通常会带来几个问题:

    费用更高
    响应更慢
    上下文更容易塞满
    模型更容易被无关信息干扰

    所以工程上要控制 token.

    不是越多越好.

    尤其是 RAG.

    如果每次检索都塞一大堆无关文档,看起来资料很多,实际可能让模型更乱.

    6.为什么中文英文token数不一样

    这个问题很多人会遇到.

    同样一句意思,中文和英文的 token 数可能不一样.

    原因是 tokenizer 的词表和切分方式不一样.

    它不是按人类语言的"字数"或"单词数"简单统计.

    比如英文里常见词可能会作为一个 token:

    hello
    world
    function

    但不常见的词可能会被拆开.

    中文里有些常见组合也可能被合在一起,有些又会被拆开.

    所以你看到:

    字符数差不多,token 数不一样

    这是正常的.

    以后写 prompt 时,不要只看文字长度.

    更重要的是:

    最终被 tokenizer 切成了多少 token.

    7.Token和RAG切块有什么关系

    这个和前面几篇 RAG 文章能接起来.

    RAG 里有一个步骤:

    把长文档切成 chunk.

    这里切块不能只按字数想.

    更准确应该考虑 token.

    因为最后塞进模型的是 token.

    比如一个 chunk 太大:

    一次塞进去占很多 token
    上下文窗口很快满
    检索出来的片段可能包含很多无关内容
    模型抓重点更困难

    chunk 太小也有问题:

    语义可能被切碎
    上下文不完整
    检索结果看起来相关,但缺少前后解释

    所以 RAG 切块本质上是在做一个平衡:

    既要让片段足够完整,
    又不能让 token 太多.

    这就是 token 对工程落地的影响.

    它不是一个纯理论概念.

    它会直接影响知识库效果.

    8.一个简单例子

    假设我们有一段文档:

    战斗监控接口用于查看战斗服运行状态.
    部署时需要配置数据库连接、服务端口和 Nginx 反向代理.

    如果直接作为文本看,我们觉得它只是两句话.

    但进入模型前,它会被拆成一串 token.

    大概可以理解成:

    [战斗] [监控] [接口] [用于] [查看] [战斗服] [运行] [状态]
    [部署] [时] [需要] [配置] [数据库] [连接] [服务] [端口] [Nginx] ...

    注意这只是帮助理解的示意.

    真实 tokenizer 不一定这么切.

    但这个例子能说明:

    模型不是拿整段中文直接算.
    它拿的是 token 序列.

    当你问:

    战斗监控接口怎么部署?

    RAG 检索到这段文档以后,也是把它作为 token 放进上下文.

    然后模型根据这些 token 继续生成回答.

    9.容易踩的几个坑

    第一个坑:

    以为 token 等于字数.

    不等于.

    字数只能粗略估计.

    第二个坑:

    以为上下文窗口越大越好.

    窗口大当然有用,但塞太多无关内容,模型也会被干扰.

    第三个坑:

    RAG 检索片段越多越好.

    不一定.

    如果 TopK 太大,上下文会变长,噪声也会变多.

    第四个坑:

    忽略输出 token.

    有时候输入不长,但模型回答很长,成本和延迟也会上来.

    第五个坑:

    Prompt 写得很啰嗦.

    该清楚的地方要清楚.

    但没必要每次都塞一堆重复废话.

    10.总结

    这篇主要想把 token 这个概念放稳.

    我现在会这样理解:

    Token 是文本进入模型前的切分单位.
    模型通过 token 读入上下文,也通过 token 生成答案.

    它会影响:

    上下文窗口
    API 计费
    生成速度
    RAG 切块
    Prompt 长度
    模型输出稳定性

    所以以后看到:

    这个模型支持多少 token
    这次请求用了多少 token
    RAG chunk 设置多少 token
    输出限制 max_tokens

    就不会觉得它只是一个计费单位.

    它其实贯穿了大模型从输入到输出的整个流程.

    最后一句话总结:

    文字进入模型之前,要先变成 token;
    模型生成答案时,也是一个 token 一个 token 往外接.

    下一篇继续往下走:

    Embedding 是什么?
    为什么文本能变成向量?
  • 相关阅读:
    后端存储实战课总结(上)
    正则核心知识点
    什么是 DeGods NFT 系列?
    [接口自动化] 禅道登录 Python+requests[纯代码]
    Kafka配置SSL信道加密
    Docker与Kubernetes集成以实现云原生应用程序:云原生在线教育平台
    19.set和map
    《FPGA设计实战演练》学习笔记(二)FPGA核心板电路设计
    文献阅读(183)MAGMA
    [附源码]计算机毕业设计JAVA婴幼儿玩具共享租售平台
  • 原文地址:https://www.cnblogs.com/FatTiger4399/p/20160196