深入大模型底层:从 Tokenization 到 Embedding 的语义探索实战

深入大模型底层:从 Tokenization 到 Embedding 的语义探索实战

  • [一、 大模型学习路径:从认知到个人作品](#一、 大模型学习路径:从认知到个人作品)
    • [1. 理论认知阶段](#1. 理论认知阶段)
    • [2. 动手应用与个人作品](#2. 动手应用与个人作品)
  • [二、 环境初始化与依赖配置](#二、 环境初始化与依赖配置)
      • [1. 初始化项目与安装依赖](#1. 初始化项目与安装依赖)
    • [2. 配置环境变量](#2. 配置环境变量)
  • [三、 核心机制解析之一:分词(Tokenization)](#三、 核心机制解析之一:分词(Tokenization))
    • [1. 为什么大模型必须进行分词?](#1. 为什么大模型必须进行分词?)
    • [2. Token 的计价与特征](#2. Token 的计价与特征)
    • [3. 代码实战:使用 `js-tiktoken` 进行编解码](#3. 代码实战:使用 js-tiktoken 进行编解码)
  • [四、 核心机制解析之二:文本嵌入(Embedding)](#四、 核心机制解析之二:文本嵌入(Embedding))
    • [1. 完整的数据流向模型](#1. 完整的数据流向模型)
    • [2. Embedding 的数学本质](#2. Embedding 的数学本质)
  • [五、 实战:构建语义相似度计算器](#五、 实战:构建语义相似度计算器)
    • 代码精讲与执行逻辑分析:
      • [1. 客户端实例化与兼容性](#1. 客户端实例化与兼容性)
      • [2. `getEmbedding` 函数的调用细节](#2. getEmbedding 函数的调用细节)
      • [3. 余弦相似度算法 (`cosineSimilarity`)](#3. 余弦相似度算法 (cosineSimilarity))
      • [4. 实验运行结果的现实意义](#4. 实验运行结果的现实意义)
  • [六、 总结](#六、 总结)

在大模型(LLM)技术日新月异的今天,作为开发者,不仅要学会如何通过 Prompt 调整输出,更需要理解其底层的运行机制。本文将从零开始构建一个实验环境,通过代码深入探讨大模型处理文本的核心流程:分词(Tokenization)文本嵌入(Embedding),并利用数学公式实现语义相似度计算。


一、 大模型学习路径:从认知到个人作品

学习大模型技术,通常需要经历从理论认知、工具应用到独立开发的过程。

1. 理论认知阶段

理解 AI 的本质是转型的第一步。业界公认的入门资源包括:

  • 吴恩达(Andrew Ng)的科普系列课程 :如 AI for EveryoneGenerative AI for Everyone 以及 AI Prompting for Everyone,适合快速建立对生成式 AI 的宏观认知。
  • Andrej Karpathy(前 Tesla AI 总监、OpenAI 联合创始人)的入门教程:其长达 3 小时的大模型入门视频深入浅出地讲透了大模型的底层原理,是理解 Transformer 架构、Attention(注意力机制)以及 Fine-tuning(微调)的必看教程。

2. 动手应用与个人作品

在具备基础认知后,应将 AI 融入日常。可以通过 NotebookLM(基于 RAG 架构的学习工具)和 Obsidian 知识库构建个人第二大脑。更进一步,则可以通过 Vibe Coding(利用大模型辅助进行全栈开发)的模式,独立完成小程序、客户管理工具或 Agent(智能体)等个人作品。


二、 环境初始化与依赖配置

在正式编写核心逻辑之前,需要初始化 Node.js 执行环境,并安装大模型开发所需的依赖库。

1. 初始化项目与安装依赖

打开终端,执行以下命令:

bash 复制代码
pnpm init
pnpm i js-tiktoken openai dotenv
  • js-tiktoken :OpenAI 官方分词器 tiktoken 的 JavaScript 版本,用于计算和处理文本的 Token。
  • openai:OpenAI 官方提供的 SDK,由于目前主流大模型平台均支持 OpenAI 兼容模式,该库可通用。
  • dotenv:用于管理环境变量,避免将敏感的 API 密钥硬编码在代码中。

2. 配置环境变量

在项目根目录下创建 .env 文件,用于存放云服务商的 API 密钥:

复制代码
DASHSCOPE_API_KEY=your_aliyun_dashscope_api_key_here

三、 核心机制解析之一:分词(Tokenization)

1. 为什么大模型必须进行分词?

大模型的本质是基于 Transformer 架构的神经网络。神经网络作为数学模型,只能接收并处理数字(向量与矩阵),无法直接理解人类的自然语言字符。 因此,必须存在一个映射机制,将文本字符转换为离散的数字符号 ID,这个转换的最小单位就是 Token。大模型的运作逻辑是:接收输入的 Token 序列,根据概率分布预测下一个 Token。

2. Token 的计价与特征

  • 计价单位:Token 是大模型输入、输出和计费的基本单位。
  • 数量换算:通常情况下,1 个英文字符大约等同于 0.3 个 Token;1 个中文字符(包含标点)大约等同于 0.6 个 Token。
  • 费用计算 :单次请求的消耗总量等于 输入 Token数 + 输出 Token数

3. 代码实战:使用 js-tiktoken 进行编解码

以下代码演示了如何使用 GPT-4 等模型通用的 cl100k_base 编码规则对中英文文本进行编码(Encode)与解码(Decode)。

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

// 1. 初始化编码器,指定使用 GPT 官方的 cl100k_base 编码规则
const enc = getEncoding('cl100k_base');

const text = "Hello, tiktoken! 你好,世界!";

// 2. 编码(Encode):将文本字符串转换为 Token ID 数组
const tokens = enc.encode(text); 
// 若输出 tokens,其形式为 [9906, 11, 443, 2206, 7454, 0, 166, 232, 227...]
console.log("Token 长度:", tokens.length);

// 3. 解码(Decode):将 Token ID 数组还原为原始文本
const decodedText = enc.decode(tokens);
console.log("还原后的文本:", decodedText);

代码细节讲解:

  • getEncoding('cl100k_base'):加载指定的词表映射规则。cl100k_base 采用 BPE(Byte Pair Encoding,字节对编码)算法,能够高效地将复杂的 UTF-8 字符切分为 Token。
  • enc.encode(text):执行切分与查表操作。它将连续的文本分割成词根或子词,并输出它们在词表中的索引数字(即 Token ID)。
  • enc.decode(tokens):逆向操作,通过数字索引重新拼接出可读的文本,确保数据在传输前后的一致性。

四、 核心机制解析之二:文本嵌入(Embedding)

分词虽然将文本变成了数字,但 Token ID 本身只是孤立的标签(例如 "苹果" 对应 102,"香蕉" 对应 205),数字大小并不代表实际的语义联系。为了让模型理解词与词之间的"相似度",必须引入 Embedding(文本嵌入)

1. 完整的数据流向模型

大模型处理文本的完整管线如下:

Prompt (文本) ⟶ Tokens (分词编码) ⟶ Embedding (向量化) ⟶ LLM Transformer (神经网络计算) ⟶ Tokens (预测输出) ⟶ Text (解码文本) \text{Prompt (文本)} \longrightarrow \text{Tokens (分词编码)} \longrightarrow \text{Embedding (向量化)} \longrightarrow \text{LLM Transformer (神经网络计算)} \longrightarrow \text{Tokens (预测输出)} \longrightarrow \text{Text (解码文本)} Prompt (文本)⟶Tokens (分词编码)⟶Embedding (向量化)⟶LLM Transformer (神经网络计算)⟶Tokens (预测输出)⟶Text (解码文本)

2. Embedding 的数学本质

Embedding 将离散的 Token ID 映射到一个高维连续向量空间 中。经过 Embedding 模型处理后,每段文本都会变成一个固定长度的浮点数数组(向量)。

例如,将维度设置为 1024 维,意味着该文本的语义被拆解到了 1024 个数学维度上。在空间中,语义相近的词或句子,其向量的距离就越接近。


五、 实战:构建语义相似度计算器

下面的完整示例展示了如何调用阿里云百炼平台的 text-embedding-v4 模型,将文本转化为 1024 维向量,并通过手写的余弦相似度算法计算文本之间的语义相关性。

javascript 复制代码
import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();

// 1. 初始化 OpenAI 客户端,配置兼容的阿里云百炼平台(DashScope)接口
const client = new OpenAI({
    apiKey: process.env.DASHSCOPE_API_KEY,
    baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
});

/**
 * 封装获取文本 Embedding 向量的函数
 * @param {string} text 待向量化的文本
 * @returns {Promise<number[]>} 返回 1024 维的浮点数数组
 */
async function getEmbedding(text) {
    const res = await client.embeddings.create({
        model: 'text-embedding-v4',
        input: text,
        dimensions: 1024 // 明确指定输出的向量维度
    });
    return res.data[0].embedding;
}

/**
 * 纯数学公式实现:计算两个高维向量的余弦相似度
 * 公式:(A · B) / (||A|| * ||B||)
 */
function cosineSimilarity(vecA, vecB) {
    let dot = 0;
    let magA = 0;
    let magB = 0;
    
    for (let i = 0; i < vecA.length; i++) {
        dot += vecA[i] * vecB[i];      // 计算分子:点积
        magA += vecA[i] ** 2;         // 计算分母 A 的模长平方
        magB += vecB[i] ** 2;         // 计算分母 B 的模长平方
    }
    
    return dot / (Math.sqrt(magA) * Math.sqrt(magB));
}

async function run() {
    // 定义三段测试文本
    const text1 = "Andrej Karpathy LLM Tokenization 分词原理";
    const text2 = "卡帕西讲解大模型BPE字词分词";
    const text3 = "今天天气晴朗,适合出门散步";

    // 2. 将文本异步转化为高维向量
    const vec1 = await getEmbedding(text1);
    const vec2 = await getEmbedding(text2);
    const vec3 = await getEmbedding(text3);

    // 3. 计算并输出相似度结果
    console.log(`文本1 与 文本2 的语义相似度: ${cosineSimilarity(vec1, vec2)}`);
    console.log(`文本1 与 文本3 的语义相似度: ${cosineSimilarity(vec1, vec3)}`);
}

run();

代码精讲与执行逻辑分析:

1. 客户端实例化与兼容性

代码通过 process.env.DASHSCOPE_API_KEY 引入密钥。通过重写 baseURL 为阿里云平台的兼容地址,实现了用标准的 OpenAI SDK 调用非 OpenAI 的国内主流大模型。

2. getEmbedding 函数的调用细节

client.embeddings.create 是标准的向量化接口。这里使用的模型是 text-embedding-v4,并通过 dimensions: 1024 限制了返回的浮点数数组长度为 1024。返回的数据结构中,向量数组位于 res.data[0].embedding

3. 余弦相似度算法 (cosineSimilarity)

余弦相似度用于衡量两个向量在方向上的夹角,其值范围在 − 1 , 1 -1, 1 −1,1 之间。越接近 1,代表夹角越小,语义越相似。

  • 分子 dot:两个向量对应位置数值相乘并累加(点积)。
  • 分母 Math.sqrt(magA) * Math.sqrt(magB):两个向量各自元素的平方和开根号(模长),两者相乘用于消除向量长度对结果的影响。

4. 实验运行结果的现实意义

在组件运行中:

  • text1(纯英文加专业术语)与 text2(中文翻译与专业代称)在字面上几乎没有相同的字符,但由于它们表达的是相同的技术主题,经由 Embedding 转化后计算出的余弦相似度通常会非常接近 1
  • text3 虽然包含了中文,但由于探讨的是天气与散步,与技术完全无关,它与 text1 计算出的相似度值会显著趋向于 0(或极低的值)。

这有力地证明了:Embedding 能够突破表层文本字符和语言的限制,准确捕捉到文本背后的深层数学语义。

六、 总结

本文从理论认知与实战开发两个维度,深入探讨了大模型(LLM)处理自然语言的底层数据流向。通过对分词(Tokenization)与文本嵌入(Embedding)的机制拆解及代码验证,可以得出以下核心结论:

  1. Token 是大模型运作与计价的基石 :神经网络作为数学模型无法直接处理自然语言,必须通过分词器(如基于 BPE 算法的 cl100k_base)将文本转化为离散的数字符号 ID(Token ID)。这是大模型接收输入并预测下一个词的最小工作单位。
  2. Embedding 赋予了文本真正的数学语义:单纯的 Token ID 无法体现词语之间的关联,而文本嵌入技术将这些离散的 ID 映射到高维连续向量空间(如 1024 维)中。通过手写的余弦相似度算法(Cosine Similarity)进行验证,证明了 Embedding 能够跨越表层字符与语言屏障,准确捕捉并计算深层的语义相关性。

掌握 文本 -> Token -> 向量 -> 语义计算 这一核心闭环,不仅有助于理解大模型的底层运作逻辑,也为后续开发检索增强生成(RAG)、智能 Agent 等高级 AI 应用奠定了坚实的技术基础。