分词与文本向量化是所有大模型应用的基础,也是区分普通使用者与开发人员的关键知识点,下面结合理论 + 本地可运行代码完整讲解。
1. Token 分词:模型运算、计费的最小单元
Token 基础计价规则
Token 是大模型处理文本的最小单位,也是接口计费统计标准,拆分逻辑不局限于单词或汉字:
- 英文文本:约 3 个英文字符折算 1 个 Token
- 中文文本:约 2 个汉字折算 1 个 Token
- 成本参考:百万 Token 调用成本仅几元,个人学习调试成本很低
文本必须分词的核心原因
- 神经网络仅能识别数字、向量、矩阵,无法直接读取文字,需要将文本转换为数字 ID 序列;
- 大模型生成逻辑是基于前文序列,预测下一个概率最高的子词,分词是生成流程的前置步骤;
- 主流 GPT 系列采用 BPE 子词拆分规则,适配中英文混合、生僻词汇、长单词等各类文本场景。
Token 编解码本地演示代码
使用开源tiktoken分词库实现文本编码、解码还原,代码可直接本地运行:
javascript
运行
ini
import { getEncoding } from 'js-tiktoken';
// GPT通用分词词典
const tokenEncoder = getEncoding('cl100k_base');
const inputText = "Hello tiktoken,大模型分词原理讲解";
// 文本转为Token数字ID数组
const tokenList = tokenEncoder.encode(inputText);
console.log('Token ID数组:', tokenList);
console.log('总Token数量:', tokenList.length);
// Token数字ID还原原始文本
const recoverText = tokenEncoder.decode(tokenList);
console.log('还原文本:', recoverText);
计费逻辑说明:用户输入内容拆分出输入 Token,模型返回内容拆分输出 Token,两者相加为本次调用总计费 Token 数量。
2. Embedding 语义向量化:让模型理解文本语义
文本完整处理链路
原始文本 → Token 分词拆分 → Embedding 转为高维向量 → Transformer 模型计算 → 输出 Token 序列 → 解码为可读文字
Embedding 核心作用
- 将自然语言转化为 1024 维浮点向量,数值区间范围 -1,1;
- 向量承载文本深层语义,语义相近的文本,在高维向量空间距离更近;
- 通过余弦相似度量化两段文本相似程度,是知识库检索、文档匹配、RAG 系统的底层核心。
向量生成 + 余弦相似度完整代码(国内阿里云百炼接口)
阿里云百炼提供兼容 OpenAI 标准的嵌入接口,国内账号可直接申请使用,代码附带密钥安全提醒:
javascript
运行
ini
import { getEncoding } from 'js-tiktoken';
import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();
// 阿里云百炼客户端初始化
// 重要安全提示:禁止将真实密钥明文上传、发布,统一存放在本地环境变量,避免资产损失
const llmClient = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1'
});
/**
* 生成文本1024维语义向量
* @param {string} text 输入文本
* @returns {number[]} 语义向量数组
*/
async function createTextEmbedding(text) {
const result = await llmClient.embeddings.create({
model: 'text-embedding-v4',
input: text,
dimensions: 1024
});
return result.data[0].embedding;
}
/**
* 计算两组向量余弦相似度,数值越接近1,语义相似度越高
* @param {number[]} vec1 向量1
* @param {number[]} vec2 向量2
* @returns {number} 相似度值 [-1, 1]
*/
function calculateCosSimilarity(vec1, vec2) {
let dotProduct = 0;
let vec1Length = 0;
let vec2Length = 0;
for (let index = 0; index < vec1.length; index++) {
dotProduct += vec1[index] * vec2[index];
vec1Length += Math.pow(vec1[index], 2);
vec2Length += Math.pow(vec2[index], 2);
}
return dotProduct / (Math.sqrt(vec1Length) * Math.sqrt(vec2Length));
}
// 本地测试语义相似度
async function runSimilarDemo() {
const textA = "Karpathy详解LLM底层BPE分词与Token机制";
const textB = "卡帕西分享大模型子词分词Tokenization原理";
const textC = "今日多云,适合外出骑行踏青";
const vecA = await createTextEmbedding(textA);
const vecB = await createTextEmbedding(textB);
const vecC = await createTextEmbedding(textC);
console.log('同类专业文本相似度:', calculateCosSimilarity(vecA, vecB));
console.log('无关文本相似度:', calculateCosSimilarity(vecA, vecC));
}
runSimilarDemo();
本地调试实操总结(原创个人经验)
我多次本地调试这套代码后,总结两个实用开发结论:
- 中文长文本生成的向量稳定性更强,短句语义相似度计算波动会更大;
- 1024 维向量做相似度计算性能充足,适合小型本地知识库;如果是十万级、百万级海量文档检索,需要搭配专业向量数据库优化查询效率。
运行效果说明:语义高度重合的两段专业文本相似度会无限接近 1;无关文本相似度趋近于 0,这套逻辑广泛用于智能问答、文档查重、知识库检索场景。