大模型底层探秘(一):分词技术如何塑造AI的“语言基因”?详解算法与代码

大模型学习路径系列(三)大模型架构

本文在前面语言模型和大模型能力的基础上,进一步解释什么是大模型,同时逐渐深入大模型智能涌现的底层原因。本文首先强调分词技术和大模型架构的重要性,并依据分割粒度进一步完成了对于分词算法的分类和代码实现

随后会继续更新不同子词分词算法原理(已更新)和代码实现,以及关于大模型架构的深入解析。欢迎点赞收藏关注,也欢迎大家指正!

第三章 大模型架构

1、引言

1.1 什么是大模型?

        想象一个能帮你解答生活琐事、创作艺术作品、编写程序,甚至推动科学发现和工程发展的“超级大脑”。这就是“大模型”。那么大模型到底是什么?

        大模型的本质:从数据到智慧的飞跃

        大模型是基于深度学习的神经网络,拥有数十亿到数千亿个参数,这些参数就像模型学会的“知识点”,通过复杂计算连接,赋予模型理解和生成语言、图像、音频等的能力。

        它们的强大主要依赖于三个要素:数据、算力、架构。

        第一,大模型在巨量文本、图像(如摄影作品、艺术插图)或多模态数据上训练,学会捕捉世界的规律。第二,大模型参数多、数据规模大的同时,而需要强大的算力支撑。模型训练需要数千GPU或TPU,耗时数周到数月完成一次训练。第三,大模型依赖于强大的模型架构和先进的算法,Transformer架构的突破让模型能够高效理解长序列信息,精准捕捉语义和上下文。

        以Grok3、DeepSeek或ChatGPT背后的GPT系列为例,这些模型通过预训练掌握通用知识,再通过微调适配特定任务,如对话、翻译或代码生成。大模型就像一个全能知识库,能快速应对各种需求。

        大模型的能力:从生活助手到推动行业变革

        大模型的真正魔力在于它们的通用性——它们能轻松应对从生活琐事到全球挑战的各种任务,宛如一位随叫随到的智慧伙伴。大模型就像一位无所不能的智能伙伴,它能在你需要时轻松解答生活中的小问题——比如教你做一道符合口味的番茄炒蛋,或是告诉你明天要不要带伞。而当灵感来临时,它又能化身创作搭档,帮你写首小诗或是生成一张充满未来感的数字画作。在工作中,它更是得力的助手,无论是帮程序员写代码,还是替律师快速梳理合同条款,都能让你事半功倍。更令人惊叹的是,这些AI正在改变医疗诊断、教育教学等各行各业,甚至推动着像蛋白质结构预测这样的重大科学突破。从日常生活到专业领域,大模型正以惊人的适应力和创造力,重新定义着我们解决问题的方式。

        最激动人心的,是大模型在科学前沿的壮举,比如DeepMind的AlphaFold。这种突破不仅改变了科学界的游戏规则,也让我们看到大模型的无限可能——它们不只是回答问题,而是为人类探索未知铺路。

        分词与架构:大模型的语言基石与智慧核心

        要理解大模型为何如此强大,分词和架构的协同作用不可忽视。分词是将文本拆解为最小意义单元(如单词、子词或字符)的过程,它是大模型理解语言的基础。比如,中文的“人工智能”可能被拆分为“人工”和“智能”,而英文的“unbelievable”可能被拆分为“un-”“believe”“-able”。高效的分词技术让模型能够处理多语言、复杂句式甚至俚语,确保从日常对话到学术论文的文本都能被准确解析。而架构则决定了这些分词后的单元如何被组织、理解和生成。Transformer架构通过其注意力机制(Attention),能动态聚焦文本中最重要的部分,捕捉长距离的语义关联,比如理解“他昨天买的书”中的“书”和“买”之间的关系。分词为模型提供了语言的“原料”,而架构则像一位大师级厨师,将这些原料烹饪成美味的菜肴。两者的配合使得大模型对于世界知识的学习能力突飞猛进。

        由于知识点密集且重要,关于大模型架构的部分介绍我们会分为三大部分,每一部分用一篇或者几篇博客介绍:MLP基础与架构演变、Transformer架构详解(含代码)、大模型架构类型。本文介绍第一大部分。后面两部分的更新可以期待一下,马上到来~

2、NLP基础之文本处理技术

2.1 分词

分词是将文本拆解为最小意义单元(如单词、子词或字符)的过程,是大模型处理自然语言的基础步骤。自然语言(如中文、英文)是人类可读的文本,而大模型需要将文本转化为数字表示(即 token ID)以进行计算。

        分词将文本分割成有意义的单元(如单词或短语),帮助模型更好地理解语义。例如,“我爱学习”分词后为“我”、“爱”、“学习”,每个token都承载一定的语义信息。通过分词(尤其是字词分词),可以有效控制词汇表的大小,避免语言中大量罕见词或新词导致词汇表无限膨胀。例如,“playing”和“played”可以共享词根“play”,减少冗余。

        分词能够适应不同语言的特性(如中文无明显词界、英文有空格分隔),并处理标点、表情符号等非标准文本,确保模型对多种语言和格式的兼容性。分词后的token序列为模型提供了一个标准化的输入格式,便于Transformer等架构捕捉token间的上下文关系。

        关于分词技术的分类多种多样,本文从分割粒度和语义单元出发,聚焦于分词的输出形式,更加直观,适合快速理解分词技术的核心差异。

2.1.1 Word Level

        Word Level 的分词也是基于规则的单词分词,主要基于空格或者标点进行分割。

英文分词

        直接基于空格和标点进行分割。

        输入文本:I love learning new things!

        分词器 Tokenizer:按空格或标点分割,保留标点或去除。

        输出分词:["I", "love", "learning", "new", "thing", "!"]

中文分词

        由于中文没有空格分隔,通常基于词典匹配或者规则。常见方法有,前/后向最大匹配(优先匹配词典中最长的词),双向匹配(解决歧义)。

        输入文本:我爱学习新事物

        分词器:使用词典匹配,基于前向最大匹配。

        输出分词:["我", "爱", "学习", "新", 事物"]


注意:对于英文,Word Level 分词简单,但需处理缩写(如 don't 可能分为 do 和 n't)、连字符词(如 self-driving)等特殊情况。对于中文,分词效果高度依赖词典质量和算法选择,歧义(如 乒乓球拍卖 可分为 乒乓球 + 拍卖 或 乒乓 + 球拍 + 卖)是主要挑战。Word Level 分词对未登录词 (Out-of-Vocabulary,简称OOV),如新造词、专有名词,处理能力有限

2.1.1(补充) Word Level代码实现

目标

        知行合一,理解单词分词方法,动手实现中英文分词。学会使用正则表达式、外部库Jieba,设计可扩展代码。

代码语言

        Python

实现过程

Step 1: 实现简单的英文分词

def word_tokenize_en(text):
    # 按空格分割文本
    tokens = text.split()
    return tokens
text = "I love learning"
tokens = word_tokenize_en(text)
print(tokens)

        由上图可见,虽然.split() 方法实现了英文单词的简单分词,但是标点符号与单词粘在一起,未成功分离。

Step 2: 改进英文分词,分离标点

import re

def word_tokenize_en(text):
    # 匹配单词 \w+
    # 匹配标点 [^\w\s]
    # []用于定义一个字符集,匹配方括号中的任意一个字符。
    # [^...] 表示匹配不在方括号内的任何字符
    # [^\w\s] 表示匹配任何不是字母、数字、下划线或空白字符的字符
    # r''表示原始字符串,忽略字符串中的转义字符"\"
    tokens = re.findall(r'\w+|[^\w\s]', text)
    return tokens

text = "I love learning!"
tokens = word_tokenize_en(text)
print(tokens)

Step 3: 实现中文分词

        中文没有空格分隔,需要借助分词工具。本文使用 Jieba 分词处理中文文本。Jieba是一个流行的中文分词库,基于词典和统计模型。jieba.cut()返回分词结果,需转换为list。

jieba.cut() 实现精确的分词

jieba.cut_for_search() 搜索引擎模式,在精确分词的基础上,进一步对长词进行划分。

import jieba

def word_tokenize_en(text):
    tokens = list(jieba.cut(text))
    return tokens

text = "我爱学习新事物!"
tokens = word_tokenize_en(text)
print(tokens)

Step 4: 处理中英文混合文本

        区分中英文片段,分别调用英文和中文分词逻辑。其中,中文字符的Unicode范围\u4e00-\u9fff(CJK汉字)

import re
import jieba

def word_tokenize(text):
    # 初始化分词结果
    tokens = []
    
    # 分离中英文片段
    segments = [] # 列表初始为空,用于存储文本片段,每个片段是一个元组 (lang, segment)
    current_segment = "" # 用于存储正在构建的文本片段,就是存储当前符合某标准的字符
    is_chinese = False # 表示当前字符是否为中文

    for char in text:
        # 如果最新的char是中文
        if '\u4e00' <= char <= '\u9fff':
            # 如果当前正在构建的片段不是中文 并且 当前片段不为空
            #   则将当前片段标记为en,与当前片段存入分割中;
            # 其他情况(正在构建的片段是中文 或者 当前正在构建的片段为空)
            #   则将最新字符放入正在构建的片段
            # 标记正在构建的片段是中文
            if not is_chinese and current_segment:
                segments.append(("en", current_segment))
                current_segment = char
            else:
                current_segment += char
            is_chinese = True
        else:
            if is_chinese and current_segment:
                segments.append(("zh", current_segment))
                current_segment = char
            else:
                current_segment += char
            is_chinese = False

    if current_segment:
        segments.append(("zh" if is_chinese else "en", current_segment))

    # 分别处理中英文片段
    for lang, segment in segments:
        if lang == "zh":
            # 中文使用 Jieba 分词
            seg_list = jieba.cut(segment)
            tokens.extend(seg_list)
        else:
            # 英文使用正则表达式
            seg_list = re.findall(r'\w+|[^\w\s]', segment)
            tokens.extend(seg_list)

    return tokens

# 测试
text_en = "I love learning!"
text_zh = "我爱学习新事物!"
text_mixed = "我爱learning  新things!"

print("英文:", word_tokenize(text_en))
print("中文:", word_tokenize(text_zh))
print("混合:", word_tokenize(text_mixed))

Step 5: 添加配置项(可选)

        使用类对分词器进行封装,添加参数控制行为。

keep_punctuation:决定是否保留标点。

lowercase:决定是否将英文转小写。

import re
import jieba
from typing import List

class WordLevelTokenizer:
    def __init__(self, keep_punctuation: bool = True, lowercase: bool = False):
        self.keep_punctuation = keep_punctuation
        self.lowercase = lowercase
        jieba.initialize()

    def tokenize(self, text: str):
        if self.lowercase: # 统一为小写
            text = text.lower()
        text = text.strip() # 清除字符串首尾的空白字符

        tokens = []
        segments = []
        current_segment = ""
        is_chinese = False

        for char in text:
            if '\u4e00' <= char <= '\u9fff':
                if not is_chinese and current_segment:
                    segments.append(("en", current_segment))
                    current_segment = char
                else:
                    current_segment += char
                is_chinese = True
            else:
                if is_chinese and current_segment:
                    segments.append(("zh", current_segment))
                    current_segment = char
                else:
                    current_segment += char
                is_chinese = False

        if current_segment:
            segments.append(("zh" if is_chinese else "en", current_segment))

        for lang, segment in segments:
            if lang == "zh":
                seg_list = jieba.cut(segment)
                tokens.extend(seg_list)
            else:
                if self.keep_punctuation:
                    seg_list = re.findall(r'\w+|[^\w\s]', segment)
                else:
                    seg_list = re.findall(r'\w+', segment)
                tokens.extend(seg_list)

        return tokens

# 测试
tokenizer = WordLevelTokenizer(keep_punctuation=True, lowercase=True)
print(tokenizer.tokenize("I love learning!"))
print(tokenizer.tokenize("我爱学习新事物!"))
print(tokenizer.tokenize("我爱learning 新things!"))

2.1.2 Character Level

英文分词

        将英文文本按单个字符(字母、数字、标点、空格)分割。

        输入文本: I love learning!

        分词器:逐字符分割,每个字符作为一个token

        输出分词:["I", " ", "l", "o", "v", "e", " ", "l", "e", "a", "r", "n", "i", "n", "g", "!"]

中文分词

        每个汉字或标点作为一个token,无需词典或匹配算法。

        输入文本:我爱学习

        分词器:逐汉字或标点分割。

        输出分词:["我", "爱", "学", "习"]


注意:Character Level 分词对新词、罕见词和多语言文本处理能力强,但是序列长度增加可能导致Transformer模型的计算复杂度(与序列长度平方相关)显著上升。如,使用基于单词(word)的标记器(tokenizer),单词只会是单个标记,但当转换为字母/字(character)时,它很容易变成 10 个或更多的标记(token)。

2.1.2(补充) Character Level代码实现

目标

知行合一,理解字符分词方法,动手实现中英文分词。学会使用正则表达式、外部库Jieba,设计可扩展代码。

代码语言

Python

实现过程

编写函数,将文本分割为单个字符(包括汉字、字母、数字、标点、空格),支持中英文和标点处理。

Step 1: 实现基本字符分词

Python的字符串是字符序列,直接用list()或循环遍历。

def char_tokenize(text):
    # 逐字符分割
    tokens = list(text)
    return tokens

text = "我爱learning!521"
tokens = char_tokenize(text)
print(tokens)

Step 2: 添加标点和空格过滤

char.isspace():检查是否为空格

[^\w\s]:匹配标点(非字母/数字且非空格)

def char_tokenize(text, keep_punctuation=True, keep_space=True):
    tokens = []
    for char in text:
        # 过滤掉空格和标点
        if not keep_space and char.isspace():
            continue
        if not keep_punctuation and re.match(r'[^\w\s]', char):
            continue
        tokens.append(char)
    return tokens
    
text = "我爱 learning!"
print(char_tokenize(text, keep_punctuation=True, keep_space=True))
print(char_tokenize(text, keep_punctuation=False, keep_space=False))    

Step 3: 封装

import re
from typing import List

class CharacterLevelTokenizer:
    def __init__(self, keep_spaces: bool = True, keep_punctuation: bool = True):
        self.keep_spaces = keep_spaces
        self.keep_punctuation = keep_punctuation

    def tokenize(self, text: str) -> List[str]:
        text = text.strip()
        tokens = []
        for char in text:
            if not self.keep_spaces and char.isspace():
                continue
            if not self.keep_punctuation and re.match(r'[^\w\s]', char):
                continue
            tokens.append(char)
        return tokens

    def detokenize(self, tokens: List[str]) -> str:
        return "".join(tokens)

# 测试
tokenizer = CharacterLevelTokenizer(keep_spaces=True, keep_punctuation=True)
print(tokenizer.tokenize("I love learning!"))
print(tokenizer.tokenize("我爱学习新事物!"))
print(tokenizer.tokenize("我爱learning 新things!"))

tokenizer_no_space_punct = CharacterLevelTokenizer(keep_spaces=False, keep_punctuation=False)
print(tokenizer_no_space_punct.tokenize("我爱learning 新things!"))

2.1.3 Sub-word Level(重点)

        子词Sub-word Level分词是一种介于单词分词和字符分词之间的分词方法,将文本分割为字词单元(subword units),这些单元通常是单词的片段(如词根、前缀、后缀)或高频字符组合。子词分词在现代大模型(BERT、GPT、LLaMA)中广泛使用,因其再语义表达、词汇表规模和计算效率之间取得了良好的平衡。

        子词分词将高频词或语义完整的单元保留位单一token(如英文love、中文”学习“),以捕捉语义。对于低频词或者复杂词,分解为更小的子词(如,playing → play + ##ing,人工智能 → 人工+智能),确保模型能够通过组合理解新词。

子词分词算法依赖于这样一个原则,即不应将常用词拆分为更小的子词,而应将稀有词分解为有意义的子词。

        子词分词通过算法(如Byte-Pair Encoding、Word Piece、Sentence Piece等)基于语料库统计学习子词单元。能够平衡语义完整性和序列长度,生成适中的词汇表(通常30k-100k)。


注意:Subword 分词结果高度依赖训练语料和词汇表。若语料未涵盖某些词(如专有名词),可能拆分为字符级(如 红楼梦 → 红 + 楼 + 梦)。中文标点(如 ,。!)通常作为独立 token,但需确保与英文标点(如 , .)编码一致(如 UTF-8)。


        由于子词分词是大模型常用分词技术,因此将子词分词的不同算法分别单独作为一小节进行介绍。

按照分割粒度划分的分词技术(图片来自https://github.com/luhengshiwo/LLMForEverybody

总结

        本文首先引入关于大模型的介绍,方便大家对大模型有个初步的轮廓。在介绍的基础上强调分词和架构对于大模型魔力的重要地位。本文重点介绍了根据分割粒度的分词算法分类,并给出基于单词和基于字符分词的简单代码实现,方便大家动手学习,加深对于分词算法的理解。

        由于篇幅和知识密集程度原因,关于字词分词的算法(如Byte-Pair Encoding、Word Piece、Sentence Piece等算法)会在即将更新的博客中介绍,欢迎浏览博主主页内容。留个关注,不见不散~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zheng照邻、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值