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,你就知道它限制的到底是什么了。

相关推荐
奔跑中的小象20 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南20 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang20 小时前
LangGraph 状态机实战
人工智能
刹那芳华199220 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作20 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门20 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜20 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟20 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦21 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能
阿里云云原生21 小时前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能