
自然语言处理(二):词向量与语言模型
深入理解 Word2Vec、GloVe 和 FastText 如何将词语转化为捕获语义的向量。掌握数学原理,用 Gensim 训练自己的词嵌入,理解嵌入与语言模型的关系。
自然语言处理(NLP)的发展轨迹因此发生了根本性转变,进入了“表示学习”的时代。本文将沿着这条脉络展开:从独热编码为何失效,到 Word2Vec 如何通过浅层神经网络打开新思路;从 GloVe 如何利用全局统计信息,到 FastText 如何借助子词 n-gram 处理未见过的词;最终,词嵌入与催生它们的语言模型联系起来,揭示两者之间的深层关系。

你将学到什么#

- 独热编码的局限性以及稠密嵌入如何突破这一限制
- Skip-gram 和 CBOW:两种从局部上下文中学习词向量的方法
- 负采样:让大规模词表训练变得可行的关键技巧
- GloVe:通过全局共现统计信息学习高质量词向量
- FastText:借助子词信息处理罕见词和未登录词问题
- 词嵌入与语言模型之间的联系,以及为什么神经语言模型越大效果越好
- 使用 Gensim 训练、评估和可视化词嵌入的完整流程
前置知识:第 1 部分 (文本预处理基础)、基本线性代数知识(如点积和矩阵乘法),以及对 softmax 和随机梯度下降的基本理解
从稀疏到稠密:为什么词嵌入如此重要#
独热编码的痛点#
$$\text{cat} = [1, 0, 0, 0, \ldots], \quad \text{dog} = [0, 1, 0, 0, \ldots]$$这种方法存在三个致命缺陷:
- 过于稀疏。当 $V = 50{,}000$ 时,每个向量中 99.998% 的元素都是零。存储和计算资源几乎完全浪费在这些无意义的零上。
- 缺乏语义相似性。任意两个不同的独热向量之间的点积恒为零。模型无法判断“猫”和“狗”更接近,还是“猫”和“量子”更接近——在它看来,所有不同的词都同样遥远。
- 难以泛化。如果在线性分类器中使用独热编码,每个类别需要 $V$ 个独立权重。即使模型学会了“movie”是正面情感,这对“film”也毫无帮助。
词嵌入的优势#
$$\text{cat} = [0.21, -0.34, 0.78, \ldots], \quad \text{dog} = [0.18, -0.29, 0.71, \ldots]$$这样一来,$\text{cat} \cdot \text{dog} \gg \text{cat} \cdot \text{quantum}$ ,语义相近的词能够共享参数,下游模型所需的标注数据量大幅减少,甚至可以少一两个数量级。那么问题来了:这些向量中的数字是怎么生成的?
分布假设的核心思想#
本文提到的所有方法都基于语言学家 J. R. Firth 提出的一个核心观点:“一个词的意义由它所在的上下文决定。” 换句话说,经常出现在相似上下文中的词往往具有相似的含义。
- “The cat sat on the mat” 和 “The dog sat on the mat”
- “The king ruled the kingdom” 和 “The queen ruled the kingdom” 如果我们训练一个模型,让它根据词预测上下文(或者反过来),那些成功完成任务的参数自然会捕捉到分布规律。而词嵌入正是这种预测任务的副产品。
认真对待这一假设,回报非常丰厚:训练好的词嵌入能够将语义关系编码为向量空间中近似恒定的方向,这正是经典的类比算术得以成立的原因。

Word2Vec:从局部上下文学词嵌入#
Word2Vec (Mikolov 等, 2013)是首个能够以低成本在数十亿词上训练出高质量词嵌入的工具。它有两种模式——Skip-gram 和 CBOW——都基于单隐藏层的神经网络,且没有非线性激活函数。这种极简设计正是它的核心亮点。
Skip-gram:用目标词预测上下文#
给定一个目标词,模型的任务是预测其固定窗口内的每个上下文词。例如,在句子 “the quick brown fox jumps” 中,如果窗口大小为 2,目标词 “brown” 会生成以下 4 个正样本对:
| |
模型的结构分为三层:独热输入、嵌入查找矩阵 $W \in \mathbb{R}^{V \times d}$ 、输出矩阵 $W' \in \mathbb{R}^{d \times V}$ 加上 softmax。由于输入是独热向量,嵌入层的操作退化为查表,时间复杂度仅为常数级。

一个值得注意的细节是:$\mathbf{v}_w$ 来自输入矩阵 $W$ (目标词嵌入),而 $\mathbf{v}'_c$ 来自输出矩阵 $W'$ (上下文嵌入)。训练完成后,大多数流程只保留 $W$ ,但 GloVe 后续提出,结合两个矩阵的效果更佳。
为什么有效? 如果“猫”和“狗”都能预测出“坐”、“垫子”、“跑”,梯度下降会将 $\mathbf{v}_{\text{猫}}$ 和 $\mathbf{v}_{\text{狗}}$ 推向相似的方向,否则它们无法生成相似的输出分布。分布相似性被强制转化为几何相似性。
CBOW:用上下文预测目标词#
$$\mathbf{h} = \frac{1}{2m} \sum_{j=-m,\, j \neq 0}^{m} \mathbf{v}_{w_{t+j}}, \qquad P(w_t \mid \text{上下文}) = \mathrm{softmax}(W'\mathbf{h}).$$两者的实际差异如下:
- Skip-gram 每个中心词生成 $2m$ 个训练样本,因此罕见词会被“训练” $2m$ 次,在低频词上的表现更好,但速度较慢。
- CBOW 通过平均平滑上下文,训练更快,对高频词的嵌入质量略高。
在 Web 级语料上训练通用词嵌入时,默认选择是“Skip-gram + 负采样”。
Softmax 瓶颈#
无论是 Skip-gram 还是 CBOW,都面临同一个问题: softmax 分母需要在整个词表上求和。当 $V = 100{,}000$ 、训练样本达到数十亿时,每一步梯度的计算代价是 $O(Vd)$ ,根本跑不动。 Word2Vec 的第一招就是——干脆不计算这个 softmax。
负采样:让训练飞起来#
$$J = \log \sigma(\mathbf{v}_w^\top \mathbf{v}'_c) + \sum_{i=1}^{k} \mathbb{E}_{n_i \sim P_n}\!\left[\log \sigma(-\mathbf{v}_w^\top \mathbf{v}'_{n_i})\right]$$其中 $\sigma$ 是 sigmoid 函数。几何上看,梯度会把目标词和真实上下文拉近,同时把目标词和 $k$ 个无关词推开。

两个关键工程细节:
- 噪声分布。 Word2Vec 从 $P_n(w) \propto f(w)^{0.75}$ 采样,$f(w)$ 是词的语料频率。 0.75 指数的作用是“压平”分布:如果不加指数,“the” 被采样的概率大约是 “zebra” 的 100 倍,梯度会被高频词淹没。加上指数后,罕见词作为负样本的频率提升,信息量更高。
- 速度提升。取 $k = 5$ –$15$ ,每步计算代价从 $O(Vd)$ 降到 $O((k+1)d)$ 。对于 $V = 10^5$ 、$k = 10$ 的典型设置,加速约四个数量级——这正是 Word2Vec 能在单机上处理数十亿词的根本原因。
另一个常用技巧是频率下采样:训练时按概率丢弃一部分高频词。负采样和下采样这两个看似简单的工程优化,让 Word2Vec 的训练时间从“周”缩短到“小时”。
GloVe:全局矩阵分解#
Word2Vec 采用滑动窗口的方式处理语料,始终只能看到局部信息,而无法捕捉全局结构。相比之下,GloVe(Pennington 等, 2014)选择了完全不同的思路:先一次性构建完整的词-词共现矩阵,然后对其进行低秩分解。
为什么选择共现比值?#
假设我们有两个目标词 “ice” 和 “steam”,并观察它们与一些探测词的共现概率:
| 探测词 | $P(\text{word} \mid \text{ice})$ | $P(\text{word} \mid \text{steam})$ | 比值 |
|---|---|---|---|
| solid | 高 | 低 | $\gg 1$ |
| gas | 低 | 高 | $\ll 1$ |
| water | 高 | 高 | $\approx 1$ |
| fashion | 低 | 低 | $\approx 1$ |
直接看概率时,它其实包含了两部分信息:探测词与目标词的相关性,以及探测词本身的出现频率。而通过计算比值,可以有效去除频率的影响,只保留相关性信息。 GloVe 的核心思想正是让词嵌入直接建模这种比值关系。
GloVe 的目标函数#
$$\mathbf{w}_i^\top \tilde{\mathbf{w}}_j + b_i + \tilde{b}_j \;\approx\; \log X_{ij}.$$ $$J = \sum_{i,j=1}^{V} f(X_{ij}) \left(\mathbf{w}_i^\top \tilde{\mathbf{w}}_j + b_i + \tilde{b}_j - \log X_{ij}\right)^2,$$ $$f(x) = \begin{cases} (x/x_{\max})^\alpha & \text{if } x < x_{\max} \\ 1 & \text{otherwise} \end{cases}$$(论文中取 $x_{\max} = 100$ ,$\alpha = 0.75$ 。)这个权重函数的作用有两点:一是限制高频词对(如 “the the”)对损失的主导作用;二是降低稀疏对的影响,因为这些对的计数往往带有较大的统计噪声。
从本质上讲,这就是一次低秩分解:将一个 $V \times V$ 的对数共现矩阵,用一个 $V \times d$ 的词矩阵和一个 $d \times V$ 的上下文矩阵的乘积来近似。

官方发布的 GloVe 向量实际上是 $\mathbf{w}_i + \tilde{\mathbf{w}}_i$ ——即输入向量与上下文向量相加的结果。实验表明,这种方式的效果略优于单独使用其中之一。
GloVe 与 Word2Vec 的对比#
| 对比维度 | Word2Vec | GloVe |
|---|---|---|
| 处理语料的方式 | 局部窗口(在线) | 全局共现矩阵 |
| 优化方法 | 负采样 + SGD | 加权最小二乘(实践中用 AdaGrad) |
| 内存需求 | 较低(无需存储全局统计) | 共现矩阵可能非常庞大 |
| 优势 | 支持流式处理;在小语料上表现更稳健 | 在类比任务上稍占优势;结果可复现 |
实际应用中,两者的词嵌入质量相差无几,选择时主要取决于你的语言或领域是否有现成的预训练向量集。
FastText:子词嵌入的力量#
Word2Vec 和 GloVe 为每个单词分配一个独立的向量,这种方法在实际应用中会遇到两个棘手问题:训练数据中从未见过的新词,以及像德语、土耳其语这样形态丰富的语言——一个词根可能衍生出几十种变形。FastText(Bojanowski 等, 2017)通过将每个单词表示为字符 n-gram 的集合,巧妙地解决了这两个难题。
它是如何工作的?#
以单词 “where” 为例, FastText 在其两端添加边界标记 < 和 >,然后提取所有长度为 3 到 6 的字符 n-gram,同时还将完整单词作为一个特殊标记:
- 3-gram:
<wh、whe、her、ere、re> - 4-gram:
<whe、wher、here、ere> - 5-gram 和 6-gram:类似
- 完整单词:
<where>
训练过程与 Word2Vec 的 Skip-gram 模型结合负采样方法几乎完全一致,唯一的区别是输入的“词向量”被替换为上述 n-gram 嵌入的加和。

子词嵌入的优势在哪里?#
- 未登录词的处理。推理时遇到像 “wherever” 这样的新词也不用担心,它与 “where” 和 “ever” 共享了多个 n-gram (如
whe、here、ere),即使这个词从未出现在训练集中,求和后的向量依然能反映其语义。 - 形态丰富的语言。在土耳其语、德语或芬兰语中,一个名词可能有几十种屈折变化。 FastText 通过共享 n-gram,在不同形式之间传递信息,罕见的形式也能从常见形式中“借用”语义。
- 拼写错误的鲁棒性。即使是拼错的 “teh”,它仍然与 “the” 共享多个 n-gram,最终生成的向量位置大致正确,不会偏离太远。
当然,这种设计也有代价:模型体积更大(需要为每个 n-gram 存储嵌入,而不是每个单词),训练速度也会稍慢一些。对于词表固定且简单的英语,提升可能有限;但在形态复杂的语言中,效果则非常显著。
| 应用场景 | 推荐使用 FastText | 推荐使用 Word2Vec / GloVe |
|---|---|---|
| 形态复杂语言(如德语、土耳其语、芬兰语) | 是 | 否 |
| 用户生成内容(含大量拼写错误和口语化表达) | 是 | 否 |
| 推理阶段需要处理未登录词 | 是 | 否 |
| 词表固定且干净的英语 | 都可 | 是(模型更小) |
| 内存资源极其有限 | 否 | 是 |
可视化结果#
词嵌入如果真的能够捕捉到分布式语义信息,那么将其降维到二维空间后,应该能够清晰地看到语义相关的词汇聚集在一起。尽管降维算法(如 t-SNE 或 UMAP)本身对词义一无所知,但当你用它们处理几百个训练好的词向量时,结果几乎总是符合预期:动物类词汇抱团出现,国家类词汇形成独立的区域,而与皇室相关的词汇则会聚在另一个角落。

这在实际工作中是一个非常实用的调试工具。如果你训练出来的词嵌入无法让明显相关的词汇形成聚类,那问题很可能出在数据质量、分词方式或者超参数设置上——完全不用等到运行下游任务评估就能发现问题所在。
语言模型与词嵌入#
语言模型的核心任务是为一段词语序列分配一个概率值。要训练出一个优秀的语言模型,关键在于让相似的上下文能够共享统计信息,而这种共享能力正是词嵌入所提供的。
N-gram 语言模型#
$$P(w_t \mid w_{t-n+1}, \ldots, w_{t-1}) = \frac{\text{count}(w_{t-n+1}, \ldots, w_t)}{\text{count}(w_{t-n+1}, \ldots, w_{t-1})}.$$然而,这种方法面临一个严峻的问题:数据稀疏性。假设词汇表大小为 5 万, 4-gram 模型可能涉及 $50{,}000^4 \approx 6 \times 10^{18}$ 种不同的上下文组合,其中绝大多数在任何语料库中都从未出现过。尽管 Kneser-Ney、 Witten-Bell 和改进版回退等平滑技术能在一定程度上缓解这一问题,但它们无法在语义相似的上下文之间共享信息。例如,“the cat ate”和“the kitten ate”仍然是完全独立的两个统计单元。
神经语言模型#
$$\mathbf{h} = \tanh\left(W_h \cdot [\mathbf{v}_{w_{t-n+1}}; \ldots; \mathbf{v}_{w_{t-1}}] + \mathbf{b}_h\right), \quad P(w_t \mid \text{上下文}) = \mathrm{softmax}(W_o \mathbf{h} + \mathbf{b}_o).$$由于 $\mathbf{v}_{\text{cat}} \approx \mathbf{v}_{\text{kitten}}$ ,像“the cat ate”和“the kitten ate”这样的句子会生成几乎相同的隐藏状态,从而使模型能够泛化到从未见过的组合。
实际效果令人震撼。随着语料规模的增长, n-gram 模型的困惑度很快趋于平稳——因为计数已经无法支撑进一步提升;而神经语言模型则持续优化,尤其是基于 Transformer 的语言模型表现更为突出:

核心结论来了:词嵌入是语言模型扩展的关键。没有词嵌入,每个新上下文都是一个需要单独估计的统计单元;有了词嵌入,每个新上下文都能从模型已经学到的几何结构中获益。
Word2Vec 是简化版语言模型#
回顾起来, Word2Vec 实际上是一个大幅简化的神经语言模型:
- Skip-gram 对应的语言模型是:用目标词独立预测周围的每一个词。
- CBOW 对应的语言模型是:用一组上下文词预测中心词。
这些简化设计——浅层网络、去掉非线性激活、忽略词序、用负采样替代完整的 softmax——全都为了一个目标:快速训练,充分覆盖,从而让词嵌入的几何结构在海量数据中稳定下来。完整的语言模型则在其基础上更进一步。
静态嵌入 vs. 上下文嵌入(预告)#
Word2Vec、 GloVe 和 FastText 生成的都是静态嵌入——无论“bank”出现在“river bank”还是“bank account”中,它的向量始终保持不变。这是它们的主要局限。而下一波模型——ELMo、 BERT、 GPT——生成的是上下文嵌入,每次出现都会根据上下文生成一个独特的向量。这部分内容我们将在第 5 和第 6 部分 深入探讨。
用 Gensim 实战训练#
安装依赖#
| |
训练 Word2Vec 模型#
| |
这个语料库太小了,无法生成有意义的词向量。这段代码主要是为了展示 API 的用法,而不是一个实际的训练方案。在真实场景中,建议使用至少几千万 token 的大规模语料,或者直接加载预训练的词向量。
训练 FastText 模型#
Gensim 的 FastText API 设计得与 Word2Vec 几乎一致:
| |
加载预训练的词向量#
在生产环境中,使用基于数十亿 token 训练的预训练词向量,通常比自己在小规模领域语料上训练的效果更好:
| |
测试类比推理#
| |
使用 t-SNE 可视化词向量#
| |
评估词嵌入#
当你手头有了一组向量,可以通过三种评估方法来判断它们是否靠谱。
内在评估 1:类比任务#
Google 类比数据集(Google Analogy Dataset)包含 19,544 道题目,形式类似于“Athens 之于 Greece,就像 Beijing 之于?”。如果你用一个十亿词规模的语料训练了一个 300 维的 Word2Vec 或 GloVe 模型,通常可以达到 60% 到 80% 的 top-1 准确率。这算是一个不错的健全性检查,但需要注意的是,类比任务的准确率对数据集的选择比较敏感,可能会因数据集不同而波动。
内在评估 2:词相似度#
像 WordSim-353 和 SimLex-999 这样的数据集收集了人类对词对相似度的评分。你可以用你的嵌入模型计算每对词的余弦相似度,然后与人类评分进行对比,得出 Spearman 秩相关系数 $\rho$ 。一般来说,高质量的嵌入模型在这个指标上能达到 $\rho \approx 0.6$ –$0.8$ ,具体分数取决于所用的数据集。
外在评估:下游任务#
最终唯一重要的评估标准是:这些嵌入能不能在实际任务中发挥作用,比如情感分类、命名实体识别(NER)或者信息检索?当标注数据有限时,预训练的嵌入通常能带来 2 到 10 个百分点的性能提升——而且任务数据越少,嵌入带来的收益往往越大。
快速检查#
在做任何正式评估之前,先手动检查几个词的最近邻结果。比如,“cat” 的邻居应该包括 “dog”、“kitten”、“feline”,最多再加个 “pet”。如果看到的是 “the”、“and”、“is” 这样的高频词,那很可能是忘了对高频词进行下采样处理。这种问题在跑基准测试之前就能发现,早发现早解决。
如何选择嵌入维度#
| 维度 $d$ | 适用场景 |
|---|---|
| 50 – 100 | 小规模数据集(少于 100 万 token),下游任务模型较简单 |
| 100 – 300 | 中等规模数据集,通用型嵌入;实际应用中最常用的范围 |
| 300 – 1000 | 大规模数据集(超过 10 亿 token),对嵌入质量要求较高的场景 |
随着维度的增加,收益会迅速递减:从 50 提升到 100 通常能带来显著效果,但从 300 提高到 600 对大多数任务来说几乎没什么提升。建议初始选择 100 或 300,只有在下游任务评估表明需要更高维度时,再考虑调整。
多语言现实#
Word2Vec 和 GloVe 模型最初是基于英文 Wikipedia 训练的,但当你切换到其他语言时,这些模型的核心假设会在三个方面遇到挑战。
分词方式决定了词汇表的构成。英文天然以空格作为分词依据,而中文却没有这样的便利。如果你直接拿未经分词的中文文本去跑 Word2Vec,最终得到的会是每个汉字一个向量,而不是每个词语一个向量。比如,“苹果”和“果汁”都包含“果”这个字,但它们的意思完全不同——字符级别的向量会把这些语义信号混为一谈。因此,在训练之前,记得先用 Jieba 或 PKUSeg 这样的工具对中文进行分词处理。
词频分布的特性差异显著。中文常用汉字大约有 5000 个,但多字词的数量却能达到几万甚至更多。 Word2Vec 中用于负采样的公式 $f(w)^{0.75}$ 是根据英文的 Zipf 分布曲线调优的。然而在中文、日文或韩文(CJK)语料中,我发现将指数降到 0.5 能稍微提升稀有词的向量质量,因为这些语言的长尾分布更重,低频词的占比更高。
FastText 提供了一种部分解决方案。 FastText 将词语拆解为字符 n-gram,在土耳其语、芬兰语等形态丰富的语言中表现出色。对于中文来说,这种拆解的效果相对有限——毕竟汉字本身已经是语素了——但它在处理未登录词(OOV)的专有名词时依然有用。例如,“蔡徐坤”可能从未完整出现在你的 Wikipedia 训练语料中,但它的每个字都出现过, FastText 仍然能够生成一个合理的向量。
总结一下:直接使用基于英文预训练的 Word2Vec 模型并不合适。建议针对目标语言重新训练模型,或者使用 FastText 提供的多语言子词嵌入模型,比如 cc.zh.300.bin。
静态嵌入的失败场景#
以下是一些 Word2Vec/GloVe 明显失效的例子,以及对问题的深入剖析。
多义词混淆。比如,“苹果发布了新机型”和“我吃了一个苹果”,这两句话中的“苹果”会被静态嵌入压缩成同一个向量,而且通常更偏向高频含义(比如水果)。在 WiC (Words in Context)基准测试中, GloVe 的准确率只有 58%,而 BERT 则能达到 70% 以上。这 12 个百分点的差距,正是静态嵌入无法解决多义词问题的代价。
反义词成了“邻居”。“热”和“冷”经常出现在极其相似的上下文中,比如“屋里很 X”“今天感觉 X”。结果它们的向量在空间中距离非常近。在预训练的 GloVe 模型中,vec("hot") 和 vec("cold") 的余弦相似度大约是 0.55——在某些模型版本里,这个值甚至比 vec("hot") 和 vec("warm") 的相似度还高。分布式语义模型把“能填同一个空”误认为“意思相同”,导致这种尴尬局面。
否定信息被忽略。“我不喜欢这个”和“我喜欢这个”,用 bag-of-vectors 表示时几乎没什么区别。如果靠平均词向量来做句子分类,遇到这种输入肯定挂掉。要解决这个问题,要么引入序列模型,要么换成上下文编码器。
领域漂移问题。比如,在新闻语料上训练的 Word2Vec,“transformer”会被理解成“变压器”。但在机器学习论文里,它是一种架构。问题是向量已经固定了,不重新训练就没法修正。
这些问题就是为什么大家一有算力,就毫不犹豫转向上下文嵌入的原因。
总结#
- 嵌入表达的是分布语义。如果两个词经常出现在相似的上下文中,它们在嵌入空间中的位置也会接近。这种几何邻域关系是下游模型泛化能力的基础。
- Word2Vec、 GloVe 和 FastText 是三种殊途同归的方法。 Word2Vec 通过滑动窗口捕捉局部上下文; GloVe 通过对全局共现矩阵进行分解建模; FastText 则将词拆解为字符级别的 n-gram。尽管实现路径不同,但它们生成的嵌入质量旗鼓相当。
- 负采样让训练变得高效。它用对 $k$ 个随机负样本的二分类任务替代了完整的 softmax 计算,同时通过 $f(w)^{0.75}$ 的噪声分布平滑词频,从而大幅降低计算复杂度。
- 嵌入让语言模型突破扩展瓶颈。没有嵌入时, n-gram 统计方法在语料规模增大后很快遇到天花板;而有了嵌入,神经语言模型可以通过学习到的几何结构不断优化,因为每个新上下文都能从已有的嵌入中“借力”。
- 静态嵌入有其固有的局限性。比如,“bank”这个词无论出现在“河岸”还是“账户”旁边,都只有一个固定的向量。接下来的两波技术浪潮——ELMo、 BERT 和 GPT (第 5、 6 部分)——通过引入上下文相关的动态嵌入解决了这一问题。
词嵌入为神经网络自然语言处理打开了一扇大门。当词可以像数学向量一样进行加减运算和聚类分析时,从 RNN 到 Transformer 的各种架构才得以蓬勃发展。在下一篇文章中,我们将沿着这条线索继续探讨序列建模的相关内容。
NLP 技术前沿 12 篇
- 01 自然语言处理(一):NLP 入门与文本预处理
- 02 自然语言处理(二):词向量与语言模型 当前
- 03 自然语言处理(三):RNN 与序列建模
- 04 自然语言处理(四):注意力机制与 Transformer
- 05 自然语言处理(五):BERT 与预训练模型
- 06 自然语言处理(六):GPT 与生成式语言模型
- 07 自然语言处理(七):提示工程与 In-Context Learning
- 08 自然语言处理(八):模型微调与 PEFT
- 09 自然语言处理(九):大语言模型架构深度解析
- 10 自然语言处理(十):RAG 与知识增强系统
- 11 自然语言处理(十一):多模态大模型
- 12 自然语言处理(十二):前沿技术与实战应用