LLM 分词与嵌入:从文本到向量,模型如何"读懂"你的输入

LLM 分词与嵌入:从文本到向量,模型如何"读懂"你的输入

为什么大模型不能直接处理文本?Token 是什么?Embedding 又是干什么的?本文从动手 Demo 出发,把 Tokenization 和 Embedding 这两件事串起来讲清楚。


一、神经网络只认数字

LLM 本质上是一个巨大的神经网络,内部全是矩阵乘法。矩阵里的每个元素都是 浮点数------神经网络只认数字,不认识中文、英文、emoji 这些人类字符。

所以你的 prompt 在喂给模型之前,必须走两步:

复制代码
原始文本  →  Tokenization(分词/编码) →  Token IDs(整数序列)
Token IDs  →  Embedding(嵌入/向量化)  →  向量(浮点数数组)

第一步把文字变成离散的数字 ID,第二步把 ID 变成连续的、携带语义的向量。模型真正"看到"的是第二步产出的向量。


二、Tokenization:把文字切成 token

什么是 token?

token 是 LLM 计价和工作的最小单位。模型按 token 收费,上下文窗口也用 token 计算。

一个 token 大致相当于一个常见的英文单词或单词片段,但不等于单词。具体怎么切,由编码器(tokenizer)决定。

cl100k_base 编码器

GPT-4 / GPT-4o 使用的是 cl100k_base 编码器,词汇表大小约 100,256 个 token。它基于 BPE(Byte Pair Encoding)算法,能高效覆盖多语言。

⚠️ 纠正一个常见误区 :readme 里写"1 个英文字符 ≈ 0.3 token,1 个中文字符 ≈ 0.6 token",这是错的

实际上:

  • 英文:1 token ≈ 4 个英文字符(或者说 1 个英文字符 ≈ 0.25 token),常见单词 1 个 token,生僻词会被拆成 2-3 个 token
  • 中文:1 个中文字符 ≈ 1.5~2.5 个 token,绝对不是 0.6。以 "你好,世界!" 为例,用 cl100k_base 编码大约消耗 10~12 个 token

简单验证:去 OpenAI Tokenizer 粘贴一段中英文试试就知道。

Demo:用 js-tiktoken 编解码

javascript 复制代码
import { getEncoding } from "js-tiktoken";

// js-tiktoken 把编码表打包在 npm 包里,getEncoding 是同步的,直接返回即可
const enc = getEncoding("cl100k_base");
const text = "hello tiktoken!你好,世界!";

const tokens = enc.encode(text);        // 文本 → token ID 数组
const decodedText = enc.decode(tokens); // token ID 数组 → 文本

console.log(tokens);       // [15339, 48866, 0, 57668, ...]
console.log(decodedText);  // "hello tiktoken!你好,世界!"

js-tiktokengetEncoding 是同步函数------编码表(约 5MB)全部打包进了 npm 包,不需要运行时下载。这和 Python 的 tiktoken 库不同(Python 版首次调用要联网下载编码文件,所以是阻塞的)。这套设计让 js 版即开即用,但代价是 node_modules 多占了几 MB 空间。

为什么必须分词?

两个原因:

  1. 计算效率:如果每个字符都当作独立单元,序列会非常长(中文几万个字符就爆炸)。分词把常见的词/子词合并成一个 token,显著压缩序列长度。这也解释了为什么中文比英文"贵"------中文分词粒度大,一个字符就是一个 token 甚至更多。

  2. 语义粒度:token 是 BPE 算法找到的最小语义单元。一个 token 刚好"有意义",又不至于太碎。太细(一个字一个字)没有语义,太粗(一整句话一个 token)泛化不了。


三、Embedding:给 token 赋予语义

Tokenization 只是把文字变成了整数 ID(离散符号),但整数之间没有"距离"的概念------ID 15339 和 ID 48866 在语义上近不近?只看 ID 本身,完全不知道。

Embedding 要解决的就是这个问题:把每个 token ID 映射为一个高维向量,让语义相近的词在向量空间里也相近

怎么理解"向量化"?

想象每个词都有 1024 个属性来描述它:

  • 第 1 维可能描述"动作 vs 物体"
  • 第 2 维描述"正面 vs 负面"
  • 第 3 维描述"抽象 vs 具体"
  • ......

这些维度不是人工定义的,而是训练中自动学习出来的。最终每个文本被表示为 1024 维空间的一个点

Demo:调用 Embedding API + 计算相似度

javascript 复制代码
import OpenAI from "openai";

const client = new OpenAI({
    apiKey: process.env.DASHSCOPE_API_KEY,
    baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
});

async function getEmbedding(text) {
    const res = await client.embeddings.create({
        model: "text-embedding-v4",   // 通义千问 Embedding 模型
        input: text,
        dimensions: 1024,             // 输出 1024 维向量,每个分量在 [-1, 1] 之间
    });
    return res.data[0].embedding;
}

// 余弦相似度:衡量两个向量方向的接近程度,值域 [-1, 1]
function cosineSimilarity(vecA, vecB) {
    let dot = 0, magA = 0, magB = 0;
    for (let i = 0; i < vecA.length; i++) {
        dot += vecA[i] * vecB[i];
        magA += vecA[i] ** 2;
        magB += vecB[i] ** 2;
    }
    return dot / (Math.sqrt(magA) * Math.sqrt(magB));
}

const vec1 = await getEmbedding("Andrej Karpathy LLM Tokenization 分词原理");
const vec2 = await getEmbedding("卡帕西讲解大模型BPE字词分词");  // 语义相近
const vec3 = await getEmbedding("今天天气晴朗,适合出门散步");    // 语义无关

console.log(cosineSimilarity(vec1, vec2));  // 期望 > 0.8(语义相似)
console.log(cosineSimilarity(vec1, vec3));  // 期望 < 0.5(语义无关)

余弦相似度 vs 欧氏距离

相似度计算为什么要用余弦而不是欧氏距离?因为 Embedding 向量的长度 可能受文本长度等因素影响,但方向才是语义的体现。余弦相似度只看夹角、不看长度,更符合"两句话意思近不近"的直觉。

值域是 -1, 1

  • 1:方向完全一致,语义相同
  • 0:正交,语义无关
  • -1:方向相反,语义对立

四、完整数据流

把 Tokenization 和 Embedding 串起来,LLM 处理一次对话的完整路径是:

scss 复制代码
用户输入 Prompt(文本)
    │
    ▼
Tokenizer 编码(text → token IDs)
    │  [15339, 48866, 0, 57668, 224, 5758, ...]
    ▼
Embedding 向量化(token IDs → 高维向量)
    │  [[0.23, -0.87, 0.41, ...], [-0.12, 0.93, ...], ...]
    ▼
Transformer / 神经网络推理(矩阵计算 + Attention)
    │
    ▼
输出概率分布 → 采样 → Token IDs
    │  [3621, 582, 305, ...]
    ▼
Tokenizer 解码(token IDs → text)
    │
    ▼
模型回复(文本)

关键点:

  • Tokenizer 是可逆的(encode ↔ decode),Embedding 不是------Embedding 把离散映射到连续,破坏了可逆性
  • 输入的 tokens + 输出的 tokens = 本次请求的总 token 消耗,API 按这个收费
  • Embedding 模型和生成模型通常是分开的:前者专做向量化(用于语义搜索、聚类、RAG),后者做文本生成

五、总结

概念 一句话
Tokenization 文本 → 整数序列,可逆映射,决定计价和窗口利用率
BPE 编码器 用频率统计找到最优子词切分,cl100k_base 有约 10 万个 token
Embedding Token ID → 高维浮点向量,赋予语义,不可逆
余弦相似度 衡量两个向量的语义接近程度,只看方向不看长度
完整流程 文本 → 编码 → 嵌入 → 推理 → 输出 token → 解码 → 文本

理解 Tokenization 和 Embedding 的区别和关系,是理解 LLM 底层工作机制的基础。下次看到 max_tokenscontext window,你就知道它限制的到底是什么了。

相关推荐
Databend3 小时前
在 AWS 中国峰会逛了一天,我在 Databend 展台看到了 Agent 数据基础设施的新思路
数据库·人工智能·agent
米小虾3 小时前
从 Prompt 到 Loop:2026 年 AI 工程师必须掌握的 Loop Engineering 实战指南
人工智能·agent
Bigger3 小时前
我写了一个AI图像视频生成工具,免费API+本地部署,分享给大家
人工智能·图像识别·音视频开发
神奇小汤圆3 小时前
LLM 记忆系统:从 Markdown 知识库到 Self-Governing Repo
人工智能
程序员cxuan3 小时前
GPT-5.6 还不发布?不过大家可以先看看 Codex 的白皮书。
人工智能·后端·程序员
黑暗森林观察者4 小时前
Gemini 3.5 Flash 把"操作电脑"塞进了模型——AI从"能说"到"能动手"
人工智能·gemini
埃菲尔铁桶4 小时前
我和大模型一起做了个本地知识库——用户也是我和大模型
人工智能·ai编程
To_OC4 小时前
跑通一遍 Tool Call 后,我终于搞懂大模型是怎么调用工具的
人工智能·aigc·agent