大模型基础:概念理解与 C++Token 化实现笔记

一、核心概念

1. Token 化(分词)

  1. 本质:把文本拆成大模型能 "看懂" 的最小单位(Token),并给每个单位分配唯一 ID;
  2. 举例:"C++ LLM 学习" 拆为C++、(空格)、LLM,每个字符对应一个 ID;
  3. 关键:字符级 Token 化是基础,BPE/WordPiece 是更高级的优化方式,核心都是 "文本→最小单位→ID"。

2. 词嵌入(Embedding)

  1. 本质:把 Token ID 转换成有 "语义" 的数字向量(如[0.23, -1.56, 3.11]);
  2. 维度逻辑:维度(如 768 维)是描述 Token 的 "特征数量",维度越高,能表达的语义越精细;
  3. 核心作用:让模型能通过 "数字相似度" 理解文字含义(比如 "学习" 和 "研习" 的向量数值相近)。

3. 预训练 / 微调 / 推理

|-----|------|-----------|--------------|
| 阶段 | 类比 | 目标 | 场景 |
| 预训练 | 通识教育 | 学习通用知识 | 大厂海量数据训练基础模型 |
| 微调 | 职业培训 | 适配具体场景 | 开发者用小数据优化模型 |
| 推理 | 上岗干活 | 处理新输入给出答案 | 实际使用模型 |

二、"文本→Token→Embedding" 完整转换流

  1. 文本转 Token:给文字 "贴数字标签"

    • 拆分:把一句话拆成最小文字碎片(Token);
    • 编码:给每个碎片分配唯一 ID(如C=0+=1学=5);
    • 目的:让电脑能 "数数字" 理解文字。
  2. Token 转 Embedding:给数字 "赋语义"

    • 转换:把 Token ID 变成一组有规律的数字向量;
    • 核心:语义相近的文字,对应的向量数值也相近;
    • 目的:让模型能识别文字的实际含义。

总结:人类文字 → 电脑可计数的 ID → 电脑可理解的语义向量,是大模型 "看懂文字" 的核心步骤。

三、C++ 字符级 Token 化核心逻辑(处理中英文)

1. 核心问题

中文在 UTF-8 编码下占 2~4 字节(绝大多数 3 字节),直接按单字节遍历会拆成乱码,需先识别完整字符。

2. 关键代码逻辑

复制代码
// 判断多字节字符的完整长度
unsigned char c = static_cast<unsigned char>(*it);
if (c >= 0xF0) bytes = 4;    // 4字节字符
else if (c >= 0xE0) bytes = 3;// 3字节字符
else if (c >= 0xC0) bytes = 2;// 2字节字符

// 拼接完整字符
for (int i = 0; i < bytes && it != input_text.end(); ++i, ++it) {
    current_char += *it;
}

完整代码:

复制代码
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>


std::vector<int> characterTokenize(const std::string& input_text) {
    // 存储字符到Token ID的映射(字典),初始为空
    static std::unordered_map<std::string, int> char_to_id;
    // 存储最终的Token ID列表
    std::vector<int> token_ids;
    // 下一个要分配的Token ID
    static int next_id = 0;

    // 遍历输入文本的每个字符
    // 用迭代器遍历每个字符
    for (auto it = input_text.begin(); it != input_text.end(); ) {
        // 需要处理多字节中文
        std::string current_char;

        // 单字节
        if (static_cast<unsigned char>(*it) < 128) {
            current_char = *it;
            ++it;
        }
        else {
            // 多字节
            int bytes = 0;
            unsigned char c = static_cast<unsigned char>(*it);
            if (c >= 0xF0) bytes = 4;
            else if (c >= 0xE0) bytes = 3;
            else if (c >= 0xC0) bytes = 2;
            else bytes = 1;

            // 拼接字符
            for (int i = 0; i < bytes && it != input_text.end(); ++i, ++it) {
                current_char += *it;
            }
        }

        // 如果当前字符还没有分配ID,就分配一个新的
        if (char_to_id.find(current_char) == char_to_id.end()) {
            char_to_id[current_char] = next_id++;
        }

        // 将当前字符的ID加入结果列表
        token_ids.push_back(char_to_id[current_char]);

        std::cout << "字符: \"" << current_char << "\" -> Token ID: " << char_to_id[current_char] << std::endl;
    }

    return token_ids;
}

// 测试函数
int main() {
    std::string test_text = "C++ LLM学习";
    std::cout << test_text << std::endl;

    // 调用Token化函数
    std::vector<int> result_ids = characterTokenize(test_text);

    std::cout << "Token ID列表:";
    for (int id : result_ids) {
        std::cout << id << " ";
    }
    std::cout << std::endl;

    // 额外测试
    std::cout << "\n重复测试" << std::endl;
    std::string test_text2 = "学习C++";
    std::cout << "输入文本:" << test_text2 << std::endl;
    std::vector<int> result_ids2 = characterTokenize(test_text2);
    std::cout << "\nToken ID列表:";
    for (int id : result_ids2) {
        std::cout << id << " ";
    }
    std::cout << std::endl;

    return 0;
}

3. 核心作用

  • 识别中文等多字节字符的完整长度;
  • 拼接零散字节为完整字符(如 "学" 的 3 个字节拼成一个 Token);
  • 保证 Token 化结果正确,无乱码、错拆。

四、总结

  1. Token 化是 "文本→数字 ID" 的转换,核心是拆分为最小单位并编码,处理中文需适配 UTF-8 多字节规则;
  2. Embedding 是 "ID→语义向量" 的转换,让模型能理解文字含义;
  3. 预训练 / 微调 / 推理分别对应大模型的 "学习、适配、使用" 阶段,目标和场景不同。
相关推荐
左左右右左右摇晃11 小时前
计算机网络笔记整理
笔记·计算机网络
不吃西红柿的8511 小时前
[职场] 内容运营求职简历范文 #笔记#职场发展
笔记·职场和发展·内容运营
似水明俊德12 小时前
02-C#.Net-反射-学习笔记
开发语言·笔记·学习·c#·.net
智者知已应修善业12 小时前
【51单片机独立按键控制数码管移动反向,2片74CH573/74CH273段和位,按键按下保持原状态】2023-3-25
经验分享·笔记·单片机·嵌入式硬件·算法·51单片机
C羊驼12 小时前
C语言:两天打鱼,三天晒网
c语言·经验分享·笔记·算法·青少年编程
sheeta199813 小时前
苍穹外卖Day04笔记
笔记
今儿敲了吗17 小时前
46| FBI树
数据结构·c++·笔记·学习·算法
苦瓜小生17 小时前
【黑马点评学习笔记 | 实战篇 】| 6-Redis消息队列
redis·笔记·后端
sheeta199818 小时前
LeetCode 每日一题笔记 日期:2025.03.19 题目:3212.统计X和Y频数相等的子矩阵数量
笔记·leetcode·矩阵
巧克力味的桃子19 小时前
国名排序题笔记(字符串函数 + fgets 详解)
笔记